[
  {
    "path": ".claude/CLAUDE.md",
    "content": "# Project Rules\n\n- use `uv` to run Python commands (e.g., `uv run python`, `uv run pytest`).\n- use `make test` to run tests.\n- use `make update_translate` to update translation files (`.ts` and `.qm`).\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# Format code with black\n5c9808446a179176c721bd7a59d621b41c95898c\n# Mypy check # type: ignore\n8a9cb1918d35c01abc804b40acb61f34bf8d4fc7\n1f7ece25e26ed4e421a2dff3782217967f0443aa\ne63d1b8374f7b706a91c51e7ca9478a092a81bbb\n6ba57e4a7467f73a6f388716c477639826186db6\n4c0ef54052a7fd15715be8e8a2f5ba39fba4efaa\n1b2f32ce683938d1ede0ecf956cd59e85cce0fba\ne83f3d68a69fe0a9a33c744fa428efb7a2a176b2\n80f5a31723e6be3ae614e68a4aeaef8abec2162c\n5e75e6cddf913e51ae413e58233c456bffba72ef\n6a44111aded17402d03715f8b5d816a3ba19ba2f\n34cff8833a442cfcea231e9bc5a719351f92427d\ncbb6d829725f531bdb3cb30bcb13213604a4fe31\n9998f0042bcf5287625dbcee8e900c026474a0fe\n39c9e2a979ebe52575e0e14be32ec5793e93e9fd\n28dd12c1d641fe8b0b528eda9cab75a7fe0de7f6\n50719a6268d9948e2bd08034e3ea7308d13c1bea\n4aba96809ca188f1a13f353a843cdb09c631ad22\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1.bug_report.yml",
    "content": "name: Bug Report\ndescription: Create a bug report\nlabels: 'bug'\nbody:\n  - type: markdown\n    attributes:\n      value: Thanks for taking the time to file a bug report! Please fill out this form as completely as possible.\n  - type: markdown\n    attributes:\n      value: If you leave out sections there is a high likelihood it will be moved to the GitHub Discussions [\"Q&A / Help\" section](https://github.com/wkentaro/labelme/discussions/categories/q-a-help).\n  - type: textarea\n    attributes:\n      label: Provide environment information\n      description: Please run `which python; python --version; python -m pip list | grep labelme` in the root directory of your project and paste the results.\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: What OS are you using?\n      description: 'Please specify the exact version. For example: macOS 12.4, Ubuntu 20.04.4'\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Describe the Bug\n      description: A clear and concise description of what the bug is.\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Expected Behavior\n      description: A clear and concise description of what you expected to happen.\n  - type: textarea\n    attributes:\n      label: To Reproduce\n      description: Steps to reproduce the behavior, please provide a clear description of how to reproduce the issue, based on the linked minimal reproduction. Screenshots can be provided in the issue body below. If using code blocks, make sure that [syntax highlighting is correct](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) and double check that the rendered preview is not broken.\n  - type: markdown\n    attributes:\n      value: Before posting the issue go through the steps you've written down to make sure the steps provided are detailed and clear.\n  - type: markdown\n    attributes:\n      value: Contributors should be able to follow the steps provided in order to reproduce the bug.\n  - type: markdown\n    attributes:\n      value: These steps are used to add integration tests to ensure the same issue does not happen again. Thanks in advance!\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "contact_links:\n  - name: Ideas / Feature request\n    url: https://github.com/wkentaro/labelme/discussions/categories/ideas-feature-requests\n    about: Share ideas for new features\n  - name: Q&A / Help\n    url: https://github.com/wkentaro/labelme/discussions/categories/q-a-help\n    about: Ask the community for help\n  - name: Show and tell\n    url: https://github.com/wkentaro/labelme/discussions/categories/show-and-tell\n    about: Show off something you've made\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: ci\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - uses: astral-sh/setup-uv@v5\n      with:\n        python-version: \"3.10\"\n    - uses: awalsh128/cache-apt-pkgs-action@v1\n      with:\n        packages: qttools5-dev\n        version: 1.0\n    - run: make setup\n    - run: |\n        make check\n\n  build:\n\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [windows-latest, macos-latest, ubuntu-latest]\n\n    steps:\n    - uses: actions/checkout@v4\n\n    - uses: astral-sh/setup-uv@v5\n      with:\n        python-version: \"3.10\"\n\n    - shell: bash\n      run: |\n        make setup\n\n    - uses: awalsh128/cache-apt-pkgs-action@v1\n      if: matrix.os == 'ubuntu-latest'\n      with:\n        packages: xvfb libqt5widgets5\n        version: 1.0\n    - name: Test\n      shell: bash\n      if: matrix.os == 'ubuntu-latest'\n      env:\n        MPLBACKEND: 'agg'\n      run: |\n        Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &\n        export DISPLAY=:99\n\n        make test\n\n    - name: Run examples\n      shell: bash\n      if: matrix.os != 'windows-latest'\n      env:\n        MPLBACKEND: agg\n      run: |\n        labelme --help\n        labelme --version\n        (cd examples/primitives && ../tutorial/export_json.py primitives.json && rm -rf primitives)\n        (cd examples/tutorial && rm -rf apc2016_obj3_json && ./export_json.py apc2016_obj3.json && python load_label_png.py && git checkout -- .)\n        (cd examples/semantic_segmentation && rm -rf data_dataset_voc && ./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt && git checkout -- .)\n        (cd examples/instance_segmentation && rm -rf data_dataset_voc && ./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt && git checkout -- .)\n        (cd examples/video_annotation && rm -rf data_dataset_voc && ./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt && git checkout -- .)\n\n        uv pip install 'lxml<5.0.0'  # for bbox_detection/labelme2voc.py\n        (cd examples/bbox_detection && rm -rf data_dataset_voc && ./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt && git checkout -- .)\n\n        uv pip install cython && uv pip install pycocotools  # for instance_segmentation/labelme2coco.py\n        (cd examples/instance_segmentation && rm -rf data_dataset_coco && ./labelme2coco.py data_annotated data_dataset_coco --labels labels.txt && git checkout -- .)\n\n    - name: Build wheel and install from it\n      shell: bash\n      run: |\n        uv build\n        uv pip install dist/labelme-*.whl\n"
  },
  {
    "path": ".github/workflows/cla.yml",
    "content": "name: CLA Assistant\n\non:\n  pull_request_target:\n    types: [opened, synchronize]\n  issue_comment:\n    types: [created]\n\njobs:\n  cla:\n    runs-on: ubuntu-latest\n    steps:\n      - name: CLA Assistant\n        uses: contributor-assistant/github-action@v2.6.1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}\n        with:\n          path-to-signatures: \"signatures/version1/cla.json\"\n          path-to-document: \"https://github.com/wkentaro/labelme/blob/main/CLA.md\"\n          branch: \"cla-signatures\"\n          allowlist: wkentaro,bot*\n"
  },
  {
    "path": ".github/workflows/discord-notify.yml",
    "content": "name: discord-notify\n\non:\n  pull_request:\n    types: [closed]\n    branches: [main]\n\njobs:\n  notify:\n    if: |\n      github.event.pull_request.merged == true &&\n      contains(github.event.pull_request.labels.*.name, 'feature')\n    runs-on: ubuntu-latest\n    steps:\n      - name: Send to Discord\n        env:\n          DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}\n          PR_TITLE: ${{ github.event.pull_request.title }}\n          PR_BODY: ${{ github.event.pull_request.body }}\n        run: |\n          if [[ -z \"$DISCORD_WEBHOOK\" ]]; then\n            echo \"Error: DISCORD_WEBHOOK secret not configured\"\n            exit 1\n          fi\n\n          TYPE=\"🎉 **New feature merged!** Try it in the next release\"\n          COLOR=3066993\n\n          MILESTONE=\"${{ github.event.pull_request.milestone.title }}\"\n          if [[ -z \"$MILESTONE\" ]]; then\n            MILESTONE=\"None\"\n          fi\n\n          TITLE_ESCAPED=$(echo \"$PR_TITLE\" | jq -Rs '.[:-1]')\n          BODY_ESCAPED=$(echo \"$PR_BODY\" | jq -Rs '.[:-1] | if . == \"\" then \"No description provided\" elif length > 2000 then .[0:1997] + \"...\" else . end')\n\n          curl -fsS -X POST \"$DISCORD_WEBHOOK\" \\\n            -H \"Content-Type: application/json\" \\\n            -d \"{\n              \\\"content\\\": \\\"$TYPE\\\",\n              \\\"embeds\\\": [{\n                \\\"title\\\": $TITLE_ESCAPED,\n                \\\"url\\\": \\\"${{ github.event.pull_request.html_url }}\\\",\n                \\\"color\\\": $COLOR,\n                \\\"fields\\\": [\n                  {\n                    \\\"name\\\": \\\"Pull request\\\",\n                    \\\"value\\\": \\\"[#${{ github.event.pull_request.number }}](${{ github.event.pull_request.html_url }})\\\",\n                    \\\"inline\\\": true\n                  },\n                  {\n                    \\\"name\\\": \\\"Milestone\\\",\n                    \\\"value\\\": \\\"$MILESTONE\\\",\n                    \\\"inline\\\": true\n                  },\n                  {\n                    \\\"name\\\": \\\"💬 Feedback\\\",\n                    \\\"value\\\": \\\"[Share your thoughts](https://github.com/wkentaro/labelme/discussions)\\\",\n                    \\\"inline\\\": true\n                  }\n                ],\n                \\\"footer\\\": {\n                  \\\"text\\\": $BODY_ESCAPED\n                }\n              }]\n            }\"\n"
  },
  {
    "path": ".gitignore",
    "content": "/.cache/\n/.pytest_cache/\n\n/build/\n/dist/\n/*.egg-info/\n\n*.py[cdo]\n\n.DS_Store\n.idea/\n"
  },
  {
    "path": ".gitmodules",
    "content": ""
  },
  {
    "path": ".python-version",
    "content": "3.10\n"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n- family-names: \"Wada\"\n  given-names: \"Kentaro\"\n  orcid: \"https://orcid.org/0000-0002-6347-5156\"\ntitle: \"Labelme: Image Polygonal Annotation with Python\"\ndoi: 10.5281/zenodo.5711226\nurl: \"https://github.com/wkentaro/labelme\"\nlicense: GPL-3\n"
  },
  {
    "path": "CLA.md",
    "content": "# Contributor License Agreement (CLA)\n\n*Version 1.0 — March 2026*\n\nBy submitting a pull request or otherwise contributing to this repository,\nyou agree to the following terms:\n\n1. **License Grant**: You grant Kentaro Wada a perpetual, worldwide,\n   non-exclusive, irrevocable, royalty-free license to reproduce, prepare\n   derivative works of, publicly display, publicly perform, sublicense,\n   and distribute your contribution under any license terms Kentaro Wada\n   chooses, including terms different from those of this project's\n   open-source license.\n\n2. **Representations**: You represent that (a) you are legally entitled\n   to grant the above license, and (b) your contribution is your original\n   work or you have the right to submit it under these terms.\n\n**How to sign:** When you open a pull request, the CLA Assistant bot will\nask you to sign by commenting `I have read the CLA Document and I hereby\nsign the CLA`. Signing is required before your PR can be merged.\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "Makefile",
    "content": "ifneq ($(OS),Windows_NT)\n\t# On Unix-based systems, use ANSI codes\n\tBLUE = \\033[36m\n\tBOLD_BLUE = \\033[1;36m\n\tBOLD_GREEN = \\033[1;32m\n\tRED = \\033[31m\n\tYELLOW = \\033[33m\n\tBOLD = \\033[1m\n\tNC = \\033[0m\nendif\n\nescape = $(subst $$,\\$$,$(subst \",\\\",$(subst ',\\',$(1))))\n\ndefine exec\n\t@echo \"$(BOLD_BLUE)$(call escape,$(1))$(NC)\"\n\t@$(1)\nendef\n\nhelp:\n\t@echo \"$(BOLD_GREEN)Available targets:$(NC)\"\n\t@grep -E '^[a-zA-Z_-].+:.*?# .*$$' $(MAKEFILE_LIST) | \\\n\t\tawk 'BEGIN {FS = \":.*?# \"}; \\\n\t\t{printf \"  $(BOLD_BLUE)%-20s$(NC) %s\\n\", $$1, $$2}'\n\nPACKAGE_NAME:=labelme\n\nsetup:  # Setup the development environment\n\t$(call exec,uv sync)\n\nformat:  # Format code\n\t$(call exec,uv run ruff format)\n\t$(call exec,uv run ruff check --fix)\n\nlint:\n\t$(call exec,uv run ruff format --check)\n\t$(call exec,uv run ruff check)\n\t$(call exec,uv run ty check --no-progress)\n\ncheck_translate: update_translate\n\t$(call exec,git diff --exit-code labelme/translate)\n\t@if grep -r 'type=\"unfinished\"' labelme/translate/*.ts; then \\\n\t\techo \"$(RED)Error: unfinished translations found$(NC)\"; \\\n\t\texit 1; \\\n\tfi\n\ncheck: lint check_translate # Run checks\n\ntest:  # Run tests\n\t$(call exec,uv run pytest -v tests/)\n\nupdate_translate:\n\t$(call exec,uv run --no-sync tools/update_translate.py)\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">\n  <img src=\"labelme/icons/icon-256.png\" width=\"200\" height=\"200\"><br/>labelme\n</h1>\n\n<h4 align=\"center\">\n  Image annotation with Python.\n</h4>\n\n<div align=\"center\">\n  <a href=\"https://pypi.python.org/pypi/labelme\"><img src=\"https://img.shields.io/pypi/v/labelme.svg\"></a>\n  <!-- <a href=\"https://pypi.org/project/labelme\"><img src=\"https://img.shields.io/pypi/pyversions/labelme.svg\"></a> -->\n  <a href=\"https://github.com/wkentaro/labelme/actions\"><img src=\"https://github.com/wkentaro/labelme/actions/workflows/ci.yml/badge.svg?branch=main&event=push\"></a>\n  <a href=\"https://discord.com/invite/uAjxGcJm83\"><img src=\"https://dcbadge.limes.pink/api/server/uAjxGcJm83?style=flat\"></a>\n</div>\n\n<div align=\"center\">\n  <a href=\"#installation\"><b>Installation</b></a>\n  | <a href=\"#usage\"><b>Usage</b></a>\n  | <a href=\"#examples\"><b>Examples</b></a>\n  | <a href=\"https://labelme.io\"><b>labelme.io ↗</b></a>\n  <!-- | <a href=\"https://github.com/wkentaro/labelme/discussions\"><b>Community</b></a> -->\n  <!-- | <a href=\"https://www.youtube.com/playlist?list=PLI6LvFw0iflh3o33YYnVIfOpaO0hc5Dzw\"><b>Youtube FAQ</b></a> -->\n</div>\n\n<br/>\n\n<div align=\"center\">\n  <img src=\"examples/instance_segmentation/.readme/annotation.jpg\" width=\"70%\">\n</div>\n\n## Description\n\nLabelme is a graphical image annotation tool inspired by <http://labelme.csail.mit.edu>.  \nIt is written in Python and uses Qt for its graphical interface.\n\n> Looking for a simple install without Python or Qt? Get the standalone app at **[labelme.io](https://labelme.io)**.\n\n<img src=\"examples/instance_segmentation/data_dataset_voc/JPEGImages/2011_000006.jpg\" width=\"19%\" /> <img src=\"examples/instance_segmentation/data_dataset_voc/SegmentationClass/2011_000006.png\" width=\"19%\" /> <img src=\"examples/instance_segmentation/data_dataset_voc/SegmentationClassVisualization/2011_000006.jpg\" width=\"19%\" /> <img src=\"examples/instance_segmentation/data_dataset_voc/SegmentationObject/2011_000006.png\" width=\"19%\" /> <img src=\"examples/instance_segmentation/data_dataset_voc/SegmentationObjectVisualization/2011_000006.jpg\" width=\"19%\" />  \n<i>VOC dataset example of instance segmentation.</i>\n\n<img src=\"examples/semantic_segmentation/.readme/annotation.jpg\" width=\"30%\" /> <img src=\"examples/bbox_detection/.readme/annotation.jpg\" width=\"30%\" /> <img src=\"examples/classification/.readme/annotation_cat.jpg\" width=\"35%\" />  \n<i>Other examples (semantic segmentation, bbox detection, and classification).</i>\n\n<img src=\"https://user-images.githubusercontent.com/4310419/47907116-85667800-de82-11e8-83d0-b9f4eb33268f.gif\" width=\"30%\" /> <img src=\"https://user-images.githubusercontent.com/4310419/47922172-57972880-deae-11e8-84f8-e4324a7c856a.gif\" width=\"30%\" /> <img src=\"https://user-images.githubusercontent.com/14256482/46932075-92145f00-d080-11e8-8d09-2162070ae57c.png\" width=\"32%\" />  \n<i>Various primitives (polygon, rectangle, circle, line, and point).</i>\n\n<img src=\"https://github.com/user-attachments/assets/53bf09db-b097-48b7-9f32-ab490da5ac53\" width=\"32%\" />\n<p><i>Multi-language support (English, 中文, 日本語, 한국어, Deutsch, Français, and more).</i></p>\n\n## Features\n\n- [x] Image annotation for polygon, rectangle, circle, line and point ([tutorial](examples/tutorial))\n- [x] Image flag annotation for classification and cleaning ([#166](https://github.com/wkentaro/labelme/pull/166))\n- [x] Video annotation ([video annotation](examples/video_annotation))\n- [x] GUI customization (predefined labels / flags, auto-saving, label validation, etc) ([#144](https://github.com/wkentaro/labelme/pull/144))\n- [x] Exporting VOC-format dataset for [semantic segmentation](examples/semantic_segmentation), [instance segmentation](examples/instance_segmentation)\n- [x] Exporting COCO-format dataset for [instance segmentation](examples/instance_segmentation)\n- [x] AI-assisted point-to-polygon/mask annotation by SAM, EfficientSAM models\n- [x] AI text-to-annotation by YOLO-world, SAM3 models\n\n**🌏 Available in 16 languages** - English &middot; 日本語 &middot; 한국어 &middot; 简体中文 &middot; 繁體中文 &middot; Deutsch &middot; Français &middot; Español &middot; Italiano &middot; Português &middot; Nederlands &middot; Magyar &middot; Tiếng Việt &middot; Türkçe &middot; Polski &middot; فارسی (`LANG=ja_JP.UTF-8 labelme`)\n\n\n## Installation\n\nThere are 3 options to install labelme:\n\n### Option 1: Using pip\n\nFor more detail, check [\"Install Labelme using Terminal\"](https://www.labelme.io/docs/install-labelme-terminal)\n\n```bash\npip install labelme\n\n# To install the latest version from GitHub:\n# pip install git+https://github.com/wkentaro/labelme.git\n```\n\n### Option 2: Using standalone executable (Easiest)\n\nIf you're willing to invest in the convenience of simple installation without any dependencies (Python, Qt),\nyou can download the standalone executable from [\"Install Labelme as App\"](https://www.labelme.io/docs/install-labelme-app).\n\nIt's a one-time payment for lifetime access, and it helps us to maintain this project.\n\n### Option 3: Using a package manager in each Linux distribution\n\nIn some Linux distributions, you can install labelme via their package managers (e.g., apt, pacman). The following systems are currently available:\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/labelme.svg)](https://repology.org/project/labelme/versions)\n\n## Usage\n\nRun `labelme --help` for detail.  \nThe annotations are saved as a [JSON](http://www.json.org/) file.\n\n```bash\nlabelme  # just open gui\n\n# tutorial (single image example)\ncd examples/tutorial\nlabelme apc2016_obj3.jpg  # specify image file\nlabelme apc2016_obj3.jpg --output annotations/  # save annotation JSON files to a directory\nlabelme apc2016_obj3.jpg --with-image-data  # include image data in JSON file\nlabelme apc2016_obj3.jpg \\\n  --labels highland_6539_self_stick_notes,mead_index_cards,kong_air_dog_squeakair_tennis_ball  # specify label list\n\n# semantic segmentation example\ncd examples/semantic_segmentation\nlabelme data_annotated/  # Open directory to annotate all images in it\nlabelme data_annotated/ --labels labels.txt  # specify label list with a file\n```\n\n### Command Line Arguments\n- `--output` specifies the location that annotations will be written to. If the location ends with .json, a single annotation will be written to this file. Only one image can be annotated if a location is specified with .json. If the location does not end with .json, the program will assume it is a directory. Annotations will be stored in this directory with a name that corresponds to the image that the annotation was made on.\n- The first time you run labelme, it will create a config file at `~/.labelmerc`. Add only the settings you want to override. For all available options and their defaults, see [`default_config.yaml`](labelme/config/default_config.yaml). If you would prefer to use a config file from another location, you can specify this file with the `--config` flag.\n- Without the `--nosortlabels` flag, the program will list labels in alphabetical order. When the program is run with this flag, it will display labels in the order that they are provided.\n- Flags are assigned to an entire image. [Example](examples/classification)\n- Labels are assigned to a single polygon. [Example](examples/bbox_detection)\n\n### FAQ\n\n- **How to convert JSON file to numpy array?** See [examples/tutorial](examples/tutorial#convert-to-dataset).\n- **How to load label PNG file?** See [examples/tutorial](examples/tutorial#how-to-load-label-png-file).\n- **How to get annotations for semantic segmentation?** See [examples/semantic_segmentation](examples/semantic_segmentation).\n- **How to get annotations for instance segmentation?** See [examples/instance_segmentation](examples/instance_segmentation).\n\n\n## Examples\n\n* [Image Classification](examples/classification)\n* [Bounding Box Detection](examples/bbox_detection)\n* [Semantic Segmentation](examples/semantic_segmentation)\n* [Instance Segmentation](examples/instance_segmentation)\n* [Video Annotation](examples/video_annotation)\n\n\n## How to build standalone executable\n\n```bash\nLABELME_PATH=./labelme\nOSAM_PATH=$(python -c 'import os, osam; print(os.path.dirname(osam.__file__))')\npip install 'numpy<2.0'  # numpy>=2.0 causes build errors (see #1532)\npyinstaller labelme/labelme/__main__.py \\\n  --name=Labelme \\\n  --windowed \\\n  --noconfirm \\\n  --specpath=build \\\n  --add-data=$(OSAM_PATH)/_models/yoloworld/clip/bpe_simple_vocab_16e6.txt.gz:osam/_models/yoloworld/clip \\\n  --add-data=$(LABELME_PATH)/config/default_config.yaml:labelme/config \\\n  --add-data=$(LABELME_PATH)/icons/*:labelme/icons \\\n  --add-data=$(LABELME_PATH)/translate/*:translate \\\n  --icon=$(LABELME_PATH)/icons/icon-256.png \\\n  --onedir\n```\n\n\n## Acknowledgement\n\nThis repo is the fork of [mpitid/pylabelme](https://github.com/mpitid/pylabelme).\n"
  },
  {
    "path": "examples/bbox_detection/README.md",
    "content": "# Bounding Box Detection Example\n\n\n## Usage\n\n```bash\nlabelme data_annotated --labels labels.txt\n```\n\n![](.readme/annotation.jpg)\n\n\n## Convert to VOC-format Dataset\n\n```bash\n# It generates:\n#   - data_dataset_voc/JPEGImages\n#   - data_dataset_voc/Annotations\n#   - data_dataset_voc/AnnotationsVisualization\n./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt\n```\n\n<img src=\"data_dataset_voc/JPEGImages/2011_000003.jpg\" width=\"33%\" /> <img src=\"data_dataset_voc/AnnotationsVisualization/2011_000003.jpg\" width=\"33%\" />\n\n<i>Fig1. JPEG image (left), Bounding box annotation visualization (right).</i>\n"
  },
  {
    "path": "examples/bbox_detection/data_annotated/2011_000003.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          191.0,\n          107.36900369003689\n        ],\n        [\n          313.0,\n          329.36900369003695\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          365.0,\n          83.0\n        ],\n        [\n          500.0,\n          333.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000003.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 338,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/bbox_detection/data_annotated/2011_000006.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          91.0,\n          107.0\n        ],\n        [\n          240.0,\n          330.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          178.0,\n          110.0\n        ],\n        [\n          298.0,\n          282.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          254.38461538461536,\n          115.38461538461539\n        ],\n        [\n          369.38461538461536,\n          292.38461538461536\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          395.0,\n          81.0\n        ],\n        [\n          447.0,\n          117.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000006.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/bbox_detection/data_annotated/2011_000025.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          84.0,\n          20.384615384615387\n        ],\n        [\n          435.0,\n          373.38461538461536\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          1.0,\n          99.0\n        ],\n        [\n          107.0,\n          282.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          409.0,\n          167.0\n        ],\n        [\n          500.0,\n          266.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000025.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/bbox_detection/data_dataset_voc/Annotations/2011_000003.xml",
    "content": "<annotation>\n  <folder/>\n  <filename>2011_000003.jpg</filename>\n  <database/>\n  <annotation/>\n  <image/>\n  <size>\n    <height>338</height>\n    <width>500</width>\n    <depth>3</depth>\n  </size>\n  <segmented/>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>191.0</xmin>\n      <ymin>107.36900369003689</ymin>\n      <xmax>313.0</xmax>\n      <ymax>329.36900369003695</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>365.0</xmin>\n      <ymin>83.0</ymin>\n      <xmax>500.0</xmax>\n      <ymax>333.0</ymax>\n    </bndbox>\n  </object>\n</annotation>\n"
  },
  {
    "path": "examples/bbox_detection/data_dataset_voc/Annotations/2011_000006.xml",
    "content": "<annotation>\n  <folder/>\n  <filename>2011_000006.jpg</filename>\n  <database/>\n  <annotation/>\n  <image/>\n  <size>\n    <height>375</height>\n    <width>500</width>\n    <depth>3</depth>\n  </size>\n  <segmented/>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>91.0</xmin>\n      <ymin>107.0</ymin>\n      <xmax>240.0</xmax>\n      <ymax>330.0</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>178.0</xmin>\n      <ymin>110.0</ymin>\n      <xmax>298.0</xmax>\n      <ymax>282.0</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>254.38461538461536</xmin>\n      <ymin>115.38461538461539</ymin>\n      <xmax>369.38461538461536</xmax>\n      <ymax>292.38461538461536</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>person</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>395.0</xmin>\n      <ymin>81.0</ymin>\n      <xmax>447.0</xmax>\n      <ymax>117.0</ymax>\n    </bndbox>\n  </object>\n</annotation>\n"
  },
  {
    "path": "examples/bbox_detection/data_dataset_voc/Annotations/2011_000025.xml",
    "content": "<annotation>\n  <folder/>\n  <filename>2011_000025.jpg</filename>\n  <database/>\n  <annotation/>\n  <image/>\n  <size>\n    <height>375</height>\n    <width>500</width>\n    <depth>3</depth>\n  </size>\n  <segmented/>\n  <object>\n    <name>bus</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>84.0</xmin>\n      <ymin>20.384615384615387</ymin>\n      <xmax>435.0</xmax>\n      <ymax>373.38461538461536</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>bus</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>1.0</xmin>\n      <ymin>99.0</ymin>\n      <xmax>107.0</xmax>\n      <ymax>282.0</ymax>\n    </bndbox>\n  </object>\n  <object>\n    <name>car</name>\n    <pose/>\n    <truncated/>\n    <difficult/>\n    <bndbox>\n      <xmin>409.0</xmin>\n      <ymin>167.0</ymin>\n      <xmax>500.0</xmax>\n      <ymax>266.0</ymax>\n    </bndbox>\n  </object>\n</annotation>\n"
  },
  {
    "path": "examples/bbox_detection/data_dataset_voc/class_names.txt",
    "content": "_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/bbox_detection/labelme2voc.py",
    "content": "#!/usr/bin/env python\n\n\nimport argparse\nimport glob\nimport os\nimport os.path as osp\nimport sys\n\nimport imgviz\n\nimport labelme\n\ntry:\n    import lxml.builder  # type: ignore\n    import lxml.etree  # type: ignore\nexcept ImportError:\n    print(\"Please install lxml:\\n\\n    pip install lxml\\n\")\n    sys.exit(1)\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"input_dir\", help=\"input annotated directory\")\n    parser.add_argument(\"output_dir\", help=\"output dataset directory\")\n    parser.add_argument(\"--labels\", help=\"labels file\", required=True)\n    parser.add_argument(\"--noviz\", help=\"no visualization\", action=\"store_true\")\n    args = parser.parse_args()\n\n    if osp.exists(args.output_dir):\n        print(\"Output directory already exists:\", args.output_dir)\n        sys.exit(1)\n    os.makedirs(args.output_dir)\n    os.makedirs(osp.join(args.output_dir, \"JPEGImages\"))\n    os.makedirs(osp.join(args.output_dir, \"Annotations\"))\n    if not args.noviz:\n        os.makedirs(osp.join(args.output_dir, \"AnnotationsVisualization\"))\n    print(\"Creating dataset:\", args.output_dir)\n\n    class_names = []\n    class_name_to_id = {}\n    for i, line in enumerate(open(args.labels).readlines()):\n        class_id = i - 1  # starts with -1\n        class_name = line.strip()\n        class_name_to_id[class_name] = class_id\n        if class_id == -1:\n            assert class_name == \"__ignore__\"\n            continue\n        elif class_id == 0:\n            assert class_name == \"_background_\"\n        class_names.append(class_name)\n    class_names = tuple(class_names)\n    print(\"class_names:\", class_names)\n    out_class_names_file = osp.join(args.output_dir, \"class_names.txt\")\n    with open(out_class_names_file, \"w\") as f:\n        f.writelines(\"\\n\".join(class_names))\n    print(\"Saved class_names:\", out_class_names_file)\n\n    for filename in glob.glob(osp.join(args.input_dir, \"*.json\")):\n        print(\"Generating dataset from:\", filename)\n\n        label_file = labelme.LabelFile(filename=filename)\n\n        base = osp.splitext(osp.basename(filename))[0]\n        out_img_file = osp.join(args.output_dir, \"JPEGImages\", f\"{base}.jpg\")\n        out_xml_file = osp.join(args.output_dir, \"Annotations\", f\"{base}.xml\")\n        if not args.noviz:\n            out_viz_file = osp.join(\n                args.output_dir, \"AnnotationsVisualization\", f\"{base}.jpg\"\n            )\n\n        img = labelme.utils.img_data_to_arr(label_file.imageData)\n        imgviz.io.imsave(out_img_file, img)\n\n        maker = lxml.builder.ElementMaker()\n        xml = maker.annotation(\n            maker.folder(),\n            maker.filename(f\"{base}.jpg\"),\n            maker.database(),  # e.g., The VOC2007 Database\n            maker.annotation(),  # e.g., Pascal VOC2007\n            maker.image(),  # e.g., flickr\n            maker.size(\n                maker.height(str(img.shape[0])),\n                maker.width(str(img.shape[1])),\n                maker.depth(str(img.shape[2])),\n            ),\n            maker.segmented(),\n        )\n\n        bboxes: list[list[float]] = []\n        labels = []\n        for shape in label_file.shapes:\n            if shape[\"shape_type\"] != \"rectangle\":\n                print(\n                    \"Skipping shape: label={label}, shape_type={shape_type}\".format(\n                        **shape\n                    )\n                )\n                continue\n\n            class_name = shape[\"label\"]\n            class_id = class_names.index(class_name)\n\n            (xmin, ymin), (xmax, ymax) = shape[\"points\"]\n            # swap if min is larger than max.\n            xmin, xmax = sorted([xmin, xmax])\n            ymin, ymax = sorted([ymin, ymax])\n\n            bboxes.append([ymin, xmin, ymax, xmax])\n            labels.append(class_id)\n\n            xml.append(\n                maker.object(\n                    maker.name(shape[\"label\"]),\n                    maker.pose(),\n                    maker.truncated(),\n                    maker.difficult(),\n                    maker.bndbox(\n                        maker.xmin(str(xmin)),\n                        maker.ymin(str(ymin)),\n                        maker.xmax(str(xmax)),\n                        maker.ymax(str(ymax)),\n                    ),\n                )\n            )\n\n        if not args.noviz:\n            captions: list[str] = [class_names[label] for label in labels]\n            viz = imgviz.instances2rgb(\n                image=img,\n                labels=labels,\n                bboxes=bboxes,\n                captions=captions,\n                font_size=15,\n            )\n            imgviz.io.imsave(out_viz_file, viz)\n\n        with open(out_xml_file, \"wb\") as f:\n            f.write(lxml.etree.tostring(xml, pretty_print=True))\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/bbox_detection/labels.txt",
    "content": "__ignore__\n_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/classification/README.md",
    "content": "# Classification Example\n\n\n## Usage\n\n```bash\nlabelme data_annotated --flags flags.txt\n```\n\n<img src=\".readme/annotation_cat.jpg\" width=\"100%\" />\n<img src=\".readme/annotation_dog.jpg\" width=\"100%\" />\n"
  },
  {
    "path": "examples/classification/data_annotated/0001.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {\n    \"__ignore__\": false,\n    \"cat\": true,\n    \"dog\": false\n  },\n  \"shapes\": [],\n  \"imagePath\": \"0001.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 480,\n  \"imageWidth\": 640\n}"
  },
  {
    "path": "examples/classification/data_annotated/0002.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {\n    \"__ignore__\": false,\n    \"cat\": false,\n    \"dog\": true\n  },\n  \"shapes\": [],\n  \"imagePath\": \"0002.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 480,\n  \"imageWidth\": 640\n}"
  },
  {
    "path": "examples/classification/flags.txt",
    "content": "__ignore__\ncat\ndog\n"
  },
  {
    "path": "examples/instance_segmentation/README.md",
    "content": "# Instance Segmentation Example\n\n## Annotation\n\n```bash\nlabelme data_annotated --labels labels.txt --validatelabel exact --config '{shift_auto_shape_color: -2}'\nlabelme data_annotated --labels labels.txt --labelflags '{.*: [occluded, truncated], person: [male]}'\n```\n\n![](.readme/annotation.jpg)\n\n## Convert to VOC-format Dataset\n\n```bash\n# It generates:\n#   - data_dataset_voc/JPEGImages\n#   - data_dataset_voc/SegmentationClass\n#   - data_dataset_voc/SegmentationClassNpy\n#   - data_dataset_voc/SegmentationClassVisualization\n#   - data_dataset_voc/SegmentationObject\n#   - data_dataset_voc/SegmentationObjectNpy\n#   - data_dataset_voc/SegmentationObjectVisualization\n./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt\n```\n\n<img src=\"data_dataset_voc/JPEGImages/2011_000003.jpg\" width=\"33%\" /> <img src=\"data_dataset_voc/SegmentationClassVisualization/2011_000003.jpg\" width=\"33%\" /> <img src=\"data_dataset_voc/SegmentationObjectVisualization/2011_000003.jpg\" width=\"33%\" />  \nFig 1. JPEG image (left), JPEG class label visualization (center), JPEG instance label visualization (right)\n\n\nNote that the label file contains only very low label values (ex. `0, 4, 14`), and\n`255` indicates the `__ignore__` label value (`-1` in the npy file).  \nYou can see the label PNG file by following.\n\n```bash\n../tutorial/draw_label_png.py data_dataset_voc/SegmentationClass/2011_000003.png   # left\n../tutorial/draw_label_png.py data_dataset_voc/SegmentationObject/2011_000003.png  # right\n```\n\n<img src=\".readme/draw_label_png_class.jpg\" width=\"33%\" /> <img src=\".readme/draw_label_png_object.jpg\" width=\"33%\" />\n\n\n## Convert to COCO-format Dataset\n\n```bash\n# It generates:\n#   - data_dataset_coco/JPEGImages\n#   - data_dataset_coco/annotations.json\n./labelme2coco.py data_annotated data_dataset_coco --labels labels.txt\n```\n"
  },
  {
    "path": "examples/instance_segmentation/data_annotated/2011_000003.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          250.8142292490119,\n          107.33596837944665\n        ],\n        [\n          229.8142292490119,\n          119.33596837944665\n        ],\n        [\n          221.8142292490119,\n          135.33596837944665\n        ],\n        [\n          223.8142292490119,\n          148.33596837944665\n        ],\n        [\n          217.8142292490119,\n          161.33596837944665\n        ],\n        [\n          202.8142292490119,\n          168.33596837944665\n        ],\n        [\n          192.8142292490119,\n          200.33596837944665\n        ],\n        [\n          194.8142292490119,\n          222.33596837944665\n        ],\n        [\n          199.8142292490119,\n          227.33596837944665\n        ],\n        [\n          191.8142292490119,\n          234.33596837944665\n        ],\n        [\n          197.8142292490119,\n          264.3359683794467\n        ],\n        [\n          213.8142292490119,\n          295.3359683794467\n        ],\n        [\n          214.8142292490119,\n          320.3359683794467\n        ],\n        [\n          221.8142292490119,\n          327.3359683794467\n        ],\n        [\n          235.8142292490119,\n          326.3359683794467\n        ],\n        [\n          240.8142292490119,\n          323.3359683794467\n        ],\n        [\n          235.8142292490119,\n          298.3359683794467\n        ],\n        [\n          238.8142292490119,\n          287.3359683794467\n        ],\n        [\n          234.8142292490119,\n          268.3359683794467\n        ],\n        [\n          257.81422924901193,\n          258.3359683794467\n        ],\n        [\n          264.81422924901193,\n          264.3359683794467\n        ],\n        [\n          256.81422924901193,\n          273.3359683794467\n        ],\n        [\n          259.81422924901193,\n          282.3359683794467\n        ],\n        [\n          284.81422924901193,\n          288.3359683794467\n        ],\n        [\n          297.81422924901193,\n          278.3359683794467\n        ],\n        [\n          288.81422924901193,\n          270.3359683794467\n        ],\n        [\n          281.81422924901193,\n          270.3359683794467\n        ],\n        [\n          283.81422924901193,\n          264.3359683794467\n        ],\n        [\n          292.81422924901193,\n          261.3359683794467\n        ],\n        [\n          308.81422924901193,\n          236.33596837944665\n        ],\n        [\n          313.81422924901193,\n          217.33596837944665\n        ],\n        [\n          309.81422924901193,\n          208.33596837944665\n        ],\n        [\n          312.81422924901193,\n          202.33596837944665\n        ],\n        [\n          308.81422924901193,\n          185.33596837944665\n        ],\n        [\n          291.81422924901193,\n          173.33596837944665\n        ],\n        [\n          269.81422924901193,\n          159.33596837944665\n        ],\n        [\n          261.81422924901193,\n          154.33596837944665\n        ],\n        [\n          264.81422924901193,\n          142.33596837944665\n        ],\n        [\n          273.81422924901193,\n          137.33596837944665\n        ],\n        [\n          278.81422924901193,\n          130.33596837944665\n        ],\n        [\n          270.81422924901193,\n          121.33596837944665\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          482.81422924901193,\n          87.18098682963114\n        ],\n        [\n          468.81422924901193,\n          92.18098682963114\n        ],\n        [\n          460.81422924901193,\n          112.18098682963114\n        ],\n        [\n          460.81422924901193,\n          129.18098682963114\n        ],\n        [\n          444.81422924901193,\n          139.18098682963114\n        ],\n        [\n          419.81422924901193,\n          155.18098682963114\n        ],\n        [\n          410.81422924901193,\n          165.18098682963114\n        ],\n        [\n          403.81422924901193,\n          170.18098682963114\n        ],\n        [\n          394.81422924901193,\n          172.18098682963114\n        ],\n        [\n          386.81422924901193,\n          170.18098682963114\n        ],\n        [\n          386.81422924901193,\n          186.18098682963114\n        ],\n        [\n          392.81422924901193,\n          184.18098682963114\n        ],\n        [\n          410.81422924901193,\n          189.18098682963114\n        ],\n        [\n          414.81422924901193,\n          194.18098682963114\n        ],\n        [\n          437.81422924901193,\n          191.18098682963114\n        ],\n        [\n          434.81422924901193,\n          206.18098682963114\n        ],\n        [\n          390.81422924901193,\n          197.18098682963114\n        ],\n        [\n          386.81422924901193,\n          197.18098682963114\n        ],\n        [\n          387.81422924901193,\n          210.18098682963114\n        ],\n        [\n          381.81422924901193,\n          214.18098682963114\n        ],\n        [\n          372.81422924901193,\n          214.18098682963114\n        ],\n        [\n          372.81422924901193,\n          218.18098682963114\n        ],\n        [\n          400.81422924901193,\n          272.18098682963114\n        ],\n        [\n          389.81422924901193,\n          274.18098682963114\n        ],\n        [\n          389.81422924901193,\n          276.18098682963114\n        ],\n        [\n          403.81422924901193,\n          284.18098682963114\n        ],\n        [\n          444.81422924901193,\n          285.18098682963114\n        ],\n        [\n          443.81422924901193,\n          261.18098682963114\n        ],\n        [\n          426.81422924901193,\n          246.18098682963114\n        ],\n        [\n          462.81422924901193,\n          258.18098682963114\n        ],\n        [\n          474.81422924901193,\n          272.18098682963114\n        ],\n        [\n          477.81422924901193,\n          282.18098682963114\n        ],\n        [\n          473.81422924901193,\n          291.18098682963114\n        ],\n        [\n          471.81422924901193,\n          298.18098682963114\n        ],\n        [\n          472.81422924901193,\n          319.18098682963114\n        ],\n        [\n          480.81422924901193,\n          334.18098682963114\n        ],\n        [\n          494.81422924901193,\n          337.18098682963114\n        ],\n        [\n          498.81422924901193,\n          331.18098682963114\n        ],\n        [\n          494.81422924901193,\n          310.18098682963114\n        ],\n        [\n          499.81422924901193,\n          299.18098682963114\n        ],\n        [\n          499.81422924901193,\n          92.18098682963114\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          370.81422924901193,\n          170.33596837944665\n        ],\n        [\n          366.81422924901193,\n          173.33596837944665\n        ],\n        [\n          365.81422924901193,\n          182.33596837944665\n        ],\n        [\n          368.81422924901193,\n          185.33596837944665\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"bottle\",\n      \"points\": [\n        [\n          374.81422924901193,\n          159.33596837944665\n        ],\n        [\n          369.81422924901193,\n          170.33596837944665\n        ],\n        [\n          369.81422924901193,\n          210.33596837944665\n        ],\n        [\n          375.81422924901193,\n          212.33596837944665\n        ],\n        [\n          387.81422924901193,\n          209.33596837944665\n        ],\n        [\n          385.81422924901193,\n          185.33596837944665\n        ],\n        [\n          385.81422924901193,\n          168.33596837944665\n        ],\n        [\n          385.81422924901193,\n          165.33596837944665\n        ],\n        [\n          382.81422924901193,\n          159.33596837944665\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"__ignore__\",\n      \"points\": [\n        [\n          338.81422924901193,\n          266.3359683794467\n        ],\n        [\n          313.81422924901193,\n          269.3359683794467\n        ],\n        [\n          297.81422924901193,\n          277.3359683794467\n        ],\n        [\n          282.81422924901193,\n          288.3359683794467\n        ],\n        [\n          273.81422924901193,\n          302.3359683794467\n        ],\n        [\n          272.81422924901193,\n          320.3359683794467\n        ],\n        [\n          279.81422924901193,\n          337.3359683794467\n        ],\n        [\n          428.81422924901193,\n          337.3359683794467\n        ],\n        [\n          432.81422924901193,\n          316.3359683794467\n        ],\n        [\n          423.81422924901193,\n          296.3359683794467\n        ],\n        [\n          403.81422924901193,\n          283.3359683794467\n        ],\n        [\n          370.81422924901193,\n          270.3359683794467\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000003.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 338,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/instance_segmentation/data_annotated/2011_000006.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          204.936170212766,\n          108.56382978723406\n        ],\n        [\n          183.936170212766,\n          141.56382978723406\n        ],\n        [\n          166.936170212766,\n          150.56382978723406\n        ],\n        [\n          108.93617021276599,\n          203.56382978723406\n        ],\n        [\n          92.93617021276599,\n          228.56382978723406\n        ],\n        [\n          95.93617021276599,\n          244.56382978723406\n        ],\n        [\n          105.93617021276599,\n          244.56382978723406\n        ],\n        [\n          116.93617021276599,\n          223.56382978723406\n        ],\n        [\n          163.936170212766,\n          187.56382978723406\n        ],\n        [\n          147.936170212766,\n          212.56382978723406\n        ],\n        [\n          117.93617021276599,\n          222.56382978723406\n        ],\n        [\n          108.93617021276599,\n          243.56382978723406\n        ],\n        [\n          100.93617021276599,\n          325.56382978723406\n        ],\n        [\n          135.936170212766,\n          329.56382978723406\n        ],\n        [\n          148.936170212766,\n          319.56382978723406\n        ],\n        [\n          150.936170212766,\n          295.56382978723406\n        ],\n        [\n          169.936170212766,\n          272.56382978723406\n        ],\n        [\n          171.936170212766,\n          249.56382978723406\n        ],\n        [\n          178.936170212766,\n          246.56382978723406\n        ],\n        [\n          186.936170212766,\n          225.56382978723406\n        ],\n        [\n          214.936170212766,\n          219.56382978723406\n        ],\n        [\n          242.936170212766,\n          157.56382978723406\n        ],\n        [\n          228.936170212766,\n          146.56382978723406\n        ],\n        [\n          228.936170212766,\n          125.56382978723406\n        ],\n        [\n          216.936170212766,\n          112.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          271.936170212766,\n          109.56382978723406\n        ],\n        [\n          249.936170212766,\n          110.56382978723406\n        ],\n        [\n          244.936170212766,\n          150.56382978723406\n        ],\n        [\n          215.936170212766,\n          219.56382978723406\n        ],\n        [\n          208.936170212766,\n          245.56382978723406\n        ],\n        [\n          214.936170212766,\n          220.56382978723406\n        ],\n        [\n          188.936170212766,\n          227.56382978723406\n        ],\n        [\n          170.936170212766,\n          246.56382978723406\n        ],\n        [\n          170.936170212766,\n          275.56382978723406\n        ],\n        [\n          221.936170212766,\n          278.56382978723406\n        ],\n        [\n          233.936170212766,\n          259.56382978723406\n        ],\n        [\n          246.936170212766,\n          253.56382978723406\n        ],\n        [\n          245.936170212766,\n          256.56382978723406\n        ],\n        [\n          242.936170212766,\n          251.56382978723406\n        ],\n        [\n          262.936170212766,\n          256.56382978723406\n        ],\n        [\n          304.936170212766,\n          226.56382978723406\n        ],\n        [\n          297.936170212766,\n          199.56382978723406\n        ],\n        [\n          308.936170212766,\n          164.56382978723406\n        ],\n        [\n          296.936170212766,\n          148.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          308.936170212766,\n          115.56382978723406\n        ],\n        [\n          298.936170212766,\n          145.56382978723406\n        ],\n        [\n          309.936170212766,\n          166.56382978723406\n        ],\n        [\n          297.936170212766,\n          200.56382978723406\n        ],\n        [\n          305.936170212766,\n          228.56382978723406\n        ],\n        [\n          262.936170212766,\n          258.56382978723406\n        ],\n        [\n          252.936170212766,\n          284.56382978723406\n        ],\n        [\n          272.936170212766,\n          291.56382978723406\n        ],\n        [\n          281.936170212766,\n          250.56382978723406\n        ],\n        [\n          326.936170212766,\n          235.56382978723406\n        ],\n        [\n          351.936170212766,\n          239.56382978723406\n        ],\n        [\n          365.936170212766,\n          223.56382978723406\n        ],\n        [\n          371.936170212766,\n          187.56382978723406\n        ],\n        [\n          353.936170212766,\n          168.56382978723406\n        ],\n        [\n          344.936170212766,\n          143.56382978723406\n        ],\n        [\n          336.936170212766,\n          115.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"chair\",\n      \"points\": [\n        [\n          309.7054009819968,\n          242.94844517184941\n        ],\n        [\n          282.7054009819968,\n          251.94844517184941\n        ],\n        [\n          271.7054009819968,\n          287.9484451718494\n        ],\n        [\n          175.70540098199677,\n          275.9484451718494\n        ],\n        [\n          149.70540098199677,\n          296.9484451718494\n        ],\n        [\n          151.70540098199677,\n          319.9484451718494\n        ],\n        [\n          160.70540098199677,\n          328.9484451718494\n        ],\n        [\n          165.54250204582655,\n          375.38461538461536\n        ],\n        [\n          486.7054009819968,\n          373.9484451718494\n        ],\n        [\n          498.7054009819968,\n          336.9484451718494\n        ],\n        [\n          498.7054009819968,\n          202.94844517184941\n        ],\n        [\n          454.7054009819968,\n          193.94844517184941\n        ],\n        [\n          435.7054009819968,\n          212.94844517184941\n        ],\n        [\n          368.7054009819968,\n          224.94844517184941\n        ],\n        [\n          351.7054009819968,\n          241.94844517184941\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          425.936170212766,\n          82.56382978723406\n        ],\n        [\n          404.936170212766,\n          109.56382978723406\n        ],\n        [\n          400.936170212766,\n          114.56382978723406\n        ],\n        [\n          437.936170212766,\n          114.56382978723406\n        ],\n        [\n          448.936170212766,\n          102.56382978723406\n        ],\n        [\n          446.936170212766,\n          91.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"__ignore__\",\n      \"points\": [\n        [\n          457.936170212766,\n          85.56382978723406\n        ],\n        [\n          439.936170212766,\n          117.56382978723406\n        ],\n        [\n          477.936170212766,\n          117.56382978723406\n        ],\n        [\n          474.936170212766,\n          87.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          183.936170212766,\n          140.56382978723406\n        ],\n        [\n          125.93617021276599,\n          140.56382978723406\n        ],\n        [\n          110.93617021276599,\n          187.56382978723406\n        ],\n        [\n          22.936170212765987,\n          199.56382978723406\n        ],\n        [\n          18.936170212765987,\n          218.56382978723406\n        ],\n        [\n          22.936170212765987,\n          234.56382978723406\n        ],\n        [\n          93.93617021276599,\n          239.56382978723406\n        ],\n        [\n          91.93617021276599,\n          229.56382978723406\n        ],\n        [\n          110.93617021276599,\n          203.56382978723406\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          103.93617021276599,\n          290.56382978723406\n        ],\n        [\n          58.93617021276599,\n          303.56382978723406\n        ],\n        [\n          97.93617021276599,\n          311.56382978723406\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          348.936170212766,\n          146.56382978723406\n        ],\n        [\n          472.936170212766,\n          149.56382978723406\n        ],\n        [\n          477.936170212766,\n          162.56382978723406\n        ],\n        [\n          471.936170212766,\n          196.56382978723406\n        ],\n        [\n          453.936170212766,\n          192.56382978723406\n        ],\n        [\n          434.936170212766,\n          213.56382978723406\n        ],\n        [\n          368.936170212766,\n          226.56382978723406\n        ],\n        [\n          375.936170212766,\n          187.56382978723406\n        ],\n        [\n          353.936170212766,\n          164.56382978723406\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          246.936170212766,\n          252.56382978723406\n        ],\n        [\n          219.936170212766,\n          277.56382978723406\n        ],\n        [\n          254.936170212766,\n          287.56382978723406\n        ],\n        [\n          261.936170212766,\n          256.56382978723406\n        ]\n      ],\n      \"group_id\": 0,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000006.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/instance_segmentation/data_annotated/2011_000025.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          260.936170212766,\n          23.33306055646483\n        ],\n        [\n          193.936170212766,\n          20.33306055646483\n        ],\n        [\n          124.93617021276599,\n          40.33306055646483\n        ],\n        [\n          89.93617021276599,\n          102.33306055646483\n        ],\n        [\n          81.93617021276599,\n          151.33306055646483\n        ],\n        [\n          108.93617021276599,\n          146.33306055646483\n        ],\n        [\n          88.93617021276599,\n          245.33306055646483\n        ],\n        [\n          89.93617021276599,\n          323.33306055646483\n        ],\n        [\n          116.93617021276599,\n          368.33306055646483\n        ],\n        [\n          158.936170212766,\n          369.33306055646483\n        ],\n        [\n          165.936170212766,\n          338.33306055646483\n        ],\n        [\n          347.936170212766,\n          336.33306055646483\n        ],\n        [\n          349.936170212766,\n          370.33306055646483\n        ],\n        [\n          391.936170212766,\n          374.33306055646483\n        ],\n        [\n          403.936170212766,\n          336.33306055646483\n        ],\n        [\n          425.936170212766,\n          333.33306055646483\n        ],\n        [\n          421.936170212766,\n          282.33306055646483\n        ],\n        [\n          428.936170212766,\n          253.33306055646483\n        ],\n        [\n          428.936170212766,\n          237.33306055646483\n        ],\n        [\n          409.936170212766,\n          221.33306055646483\n        ],\n        [\n          409.936170212766,\n          151.33306055646483\n        ],\n        [\n          430.936170212766,\n          144.33306055646483\n        ],\n        [\n          433.936170212766,\n          113.33306055646483\n        ],\n        [\n          431.936170212766,\n          97.33306055646483\n        ],\n        [\n          408.936170212766,\n          91.33306055646483\n        ],\n        [\n          395.936170212766,\n          51.33306055646483\n        ],\n        [\n          338.936170212766,\n          26.33306055646483\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          88.93617021276599,\n          115.56382978723406\n        ],\n        [\n          0.9361702127659877,\n          96.56382978723406\n        ],\n        [\n          0.0,\n          251.968085106388\n        ],\n        [\n          0.9361702127659877,\n          265.56382978723406\n        ],\n        [\n          27.936170212765987,\n          265.56382978723406\n        ],\n        [\n          29.936170212765987,\n          283.56382978723406\n        ],\n        [\n          63.93617021276599,\n          281.56382978723406\n        ],\n        [\n          89.93617021276599,\n          252.56382978723406\n        ],\n        [\n          100.93617021276599,\n          183.56382978723406\n        ],\n        [\n          108.93617021276599,\n          145.56382978723406\n        ],\n        [\n          81.93617021276599,\n          151.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          413.936170212766,\n          168.94844517184944\n        ],\n        [\n          497.936170212766,\n          168.94844517184944\n        ],\n        [\n          497.936170212766,\n          256.94844517184936\n        ],\n        [\n          431.936170212766,\n          258.94844517184936\n        ],\n        [\n          430.936170212766,\n          236.94844517184944\n        ],\n        [\n          408.936170212766,\n          218.94844517184944\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000025.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/instance_segmentation/data_dataset_coco/annotations.json",
    "content": "{\"info\": {\"description\": null, \"url\": null, \"version\": null, \"year\": 2020, \"contributor\": null, \"date_created\": \"2020-01-26 05:46:30.244442\"}, \"licenses\": [{\"url\": null, \"id\": 0, \"name\": null}], \"images\": [{\"license\": 0, \"url\": null, \"file_name\": \"JPEGImages/2011_000003.jpg\", \"height\": 338, \"width\": 500, \"date_captured\": null, \"id\": 0}, {\"license\": 0, \"url\": null, \"file_name\": \"JPEGImages/2011_000025.jpg\", \"height\": 375, \"width\": 500, \"date_captured\": null, \"id\": 1}, {\"license\": 0, \"url\": null, \"file_name\": \"JPEGImages/2011_000006.jpg\", \"height\": 375, \"width\": 500, \"date_captured\": null, \"id\": 2}], \"type\": \"instances\", \"annotations\": [{\"id\": 0, \"image_id\": 0, \"category_id\": 15, \"segmentation\": [[250.8142292490119, 107.33596837944665, 229.8142292490119, 119.33596837944665, 221.8142292490119, 135.33596837944665, 223.8142292490119, 148.33596837944665, 217.8142292490119, 161.33596837944665, 202.8142292490119, 168.33596837944665, 192.8142292490119, 200.33596837944665, 194.8142292490119, 222.33596837944665, 199.8142292490119, 227.33596837944665, 191.8142292490119, 234.33596837944665, 197.8142292490119, 264.3359683794467, 213.8142292490119, 295.3359683794467, 214.8142292490119, 320.3359683794467, 221.8142292490119, 327.3359683794467, 235.8142292490119, 326.3359683794467, 240.8142292490119, 323.3359683794467, 235.8142292490119, 298.3359683794467, 238.8142292490119, 287.3359683794467, 234.8142292490119, 268.3359683794467, 257.81422924901193, 258.3359683794467, 264.81422924901193, 264.3359683794467, 256.81422924901193, 273.3359683794467, 259.81422924901193, 282.3359683794467, 284.81422924901193, 288.3359683794467, 297.81422924901193, 278.3359683794467, 288.81422924901193, 270.3359683794467, 281.81422924901193, 270.3359683794467, 283.81422924901193, 264.3359683794467, 292.81422924901193, 261.3359683794467, 308.81422924901193, 236.33596837944665, 313.81422924901193, 217.33596837944665, 309.81422924901193, 208.33596837944665, 312.81422924901193, 202.33596837944665, 308.81422924901193, 185.33596837944665, 291.81422924901193, 173.33596837944665, 269.81422924901193, 159.33596837944665, 261.81422924901193, 154.33596837944665, 264.81422924901193, 142.33596837944665, 273.81422924901193, 137.33596837944665, 278.81422924901193, 130.33596837944665, 270.81422924901193, 121.33596837944665]], \"area\": 15689.0, \"bbox\": [191.0, 107.0, 123.0, 221.0], \"iscrowd\": 0}, {\"id\": 1, \"image_id\": 0, \"category_id\": 15, \"segmentation\": [[482.81422924901193, 87.18098682963114, 468.81422924901193, 92.18098682963114, 460.81422924901193, 112.18098682963114, 460.81422924901193, 129.18098682963114, 444.81422924901193, 139.18098682963114, 419.81422924901193, 155.18098682963114, 410.81422924901193, 165.18098682963114, 403.81422924901193, 170.18098682963114, 394.81422924901193, 172.18098682963114, 386.81422924901193, 170.18098682963114, 386.81422924901193, 186.18098682963114, 392.81422924901193, 184.18098682963114, 410.81422924901193, 189.18098682963114, 414.81422924901193, 194.18098682963114, 437.81422924901193, 191.18098682963114, 434.81422924901193, 206.18098682963114, 390.81422924901193, 197.18098682963114, 386.81422924901193, 197.18098682963114, 387.81422924901193, 210.18098682963114, 381.81422924901193, 214.18098682963114, 372.81422924901193, 214.18098682963114, 372.81422924901193, 218.18098682963114, 400.81422924901193, 272.18098682963114, 389.81422924901193, 274.18098682963114, 389.81422924901193, 276.18098682963114, 403.81422924901193, 284.18098682963114, 444.81422924901193, 285.18098682963114, 443.81422924901193, 261.18098682963114, 426.81422924901193, 246.18098682963114, 462.81422924901193, 258.18098682963114, 474.81422924901193, 272.18098682963114, 477.81422924901193, 282.18098682963114, 473.81422924901193, 291.18098682963114, 471.81422924901193, 298.18098682963114, 472.81422924901193, 319.18098682963114, 480.81422924901193, 334.18098682963114, 494.81422924901193, 337.18098682963114, 498.81422924901193, 331.18098682963114, 494.81422924901193, 310.18098682963114, 499.81422924901193, 299.18098682963114, 499.81422924901193, 92.18098682963114], [370.81422924901193, 170.33596837944665, 366.81422924901193, 173.33596837944665, 365.81422924901193, 182.33596837944665, 368.81422924901193, 185.33596837944665]], \"area\": 17254.0, \"bbox\": [365.0, 87.0, 135.0, 251.0], \"iscrowd\": 0}, {\"id\": 2, \"image_id\": 0, \"category_id\": 5, \"segmentation\": [[374.81422924901193, 159.33596837944665, 369.81422924901193, 170.33596837944665, 369.81422924901193, 210.33596837944665, 375.81422924901193, 212.33596837944665, 387.81422924901193, 209.33596837944665, 385.81422924901193, 185.33596837944665, 385.81422924901193, 168.33596837944665, 385.81422924901193, 165.33596837944665, 382.81422924901193, 159.33596837944665]], \"area\": 873.0, \"bbox\": [369.0, 159.0, 19.0, 54.0], \"iscrowd\": 0}, {\"id\": 3, \"image_id\": 1, \"category_id\": 6, \"segmentation\": [[260.936170212766, 23.33306055646483, 193.936170212766, 20.33306055646483, 124.93617021276599, 40.33306055646483, 89.93617021276599, 102.33306055646483, 81.93617021276599, 151.33306055646483, 108.93617021276599, 146.33306055646483, 88.93617021276599, 245.33306055646483, 89.93617021276599, 323.33306055646483, 116.93617021276599, 368.33306055646483, 158.936170212766, 369.33306055646483, 165.936170212766, 338.33306055646483, 347.936170212766, 336.33306055646483, 349.936170212766, 370.33306055646483, 391.936170212766, 374.33306055646483, 403.936170212766, 336.33306055646483, 425.936170212766, 333.33306055646483, 421.936170212766, 282.33306055646483, 428.936170212766, 253.33306055646483, 428.936170212766, 237.33306055646483, 409.936170212766, 221.33306055646483, 409.936170212766, 151.33306055646483, 430.936170212766, 144.33306055646483, 433.936170212766, 113.33306055646483, 431.936170212766, 97.33306055646483, 408.936170212766, 91.33306055646483, 395.936170212766, 51.33306055646483, 338.936170212766, 26.33306055646483]], \"area\": 102701.0, \"bbox\": [81.0, 20.0, 353.0, 355.0], \"iscrowd\": 0}, {\"id\": 4, \"image_id\": 1, \"category_id\": 6, \"segmentation\": [[88.93617021276599, 115.56382978723406, 0.9361702127659877, 96.56382978723406, 0.0, 251.968085106388, 0.9361702127659877, 265.56382978723406, 27.936170212765987, 265.56382978723406, 29.936170212765987, 283.56382978723406, 63.93617021276599, 281.56382978723406, 89.93617021276599, 252.56382978723406, 100.93617021276599, 183.56382978723406, 108.93617021276599, 145.56382978723406, 81.93617021276599, 151.56382978723406]], \"area\": 15781.0, \"bbox\": [0.0, 96.0, 109.0, 188.0], \"iscrowd\": 0}, {\"id\": 5, \"image_id\": 1, \"category_id\": 7, \"segmentation\": [[413.936170212766, 168.94844517184944, 497.936170212766, 168.94844517184944, 497.936170212766, 256.94844517184936, 431.936170212766, 258.94844517184936, 430.936170212766, 236.94844517184944, 408.936170212766, 218.94844517184944]], \"area\": 7256.0, \"bbox\": [408.0, 168.0, 90.0, 91.0], \"iscrowd\": 0}, {\"id\": 6, \"image_id\": 2, \"category_id\": 15, \"segmentation\": [[204.936170212766, 108.56382978723406, 183.936170212766, 141.56382978723406, 166.936170212766, 150.56382978723406, 108.93617021276599, 203.56382978723406, 92.93617021276599, 228.56382978723406, 95.93617021276599, 244.56382978723406, 105.93617021276599, 244.56382978723406, 116.93617021276599, 223.56382978723406, 163.936170212766, 187.56382978723406, 147.936170212766, 212.56382978723406, 117.93617021276599, 222.56382978723406, 108.93617021276599, 243.56382978723406, 100.93617021276599, 325.56382978723406, 135.936170212766, 329.56382978723406, 148.936170212766, 319.56382978723406, 150.936170212766, 295.56382978723406, 169.936170212766, 272.56382978723406, 171.936170212766, 249.56382978723406, 178.936170212766, 246.56382978723406, 186.936170212766, 225.56382978723406, 214.936170212766, 219.56382978723406, 242.936170212766, 157.56382978723406, 228.936170212766, 146.56382978723406, 228.936170212766, 125.56382978723406, 216.936170212766, 112.56382978723406]], \"area\": 15203.0, \"bbox\": [92.0, 108.0, 151.0, 222.0], \"iscrowd\": 0}, {\"id\": 7, \"image_id\": 2, \"category_id\": 15, \"segmentation\": [[271.936170212766, 109.56382978723406, 249.936170212766, 110.56382978723406, 244.936170212766, 150.56382978723406, 215.936170212766, 219.56382978723406, 208.936170212766, 245.56382978723406, 214.936170212766, 220.56382978723406, 188.936170212766, 227.56382978723406, 170.936170212766, 246.56382978723406, 170.936170212766, 275.56382978723406, 221.936170212766, 278.56382978723406, 233.936170212766, 259.56382978723406, 246.936170212766, 253.56382978723406, 245.936170212766, 256.56382978723406, 242.936170212766, 251.56382978723406, 262.936170212766, 256.56382978723406, 304.936170212766, 226.56382978723406, 297.936170212766, 199.56382978723406, 308.936170212766, 164.56382978723406, 296.936170212766, 148.56382978723406]], \"area\": 11735.0, \"bbox\": [170.0, 109.0, 139.0, 170.0], \"iscrowd\": 0}, {\"id\": 8, \"image_id\": 2, \"category_id\": 15, \"segmentation\": [[308.936170212766, 115.56382978723406, 298.936170212766, 145.56382978723406, 309.936170212766, 166.56382978723406, 297.936170212766, 200.56382978723406, 305.936170212766, 228.56382978723406, 262.936170212766, 258.56382978723406, 252.936170212766, 284.56382978723406, 272.936170212766, 291.56382978723406, 281.936170212766, 250.56382978723406, 326.936170212766, 235.56382978723406, 351.936170212766, 239.56382978723406, 365.936170212766, 223.56382978723406, 371.936170212766, 187.56382978723406, 353.936170212766, 168.56382978723406, 344.936170212766, 143.56382978723406, 336.936170212766, 115.56382978723406]], \"area\": 7597.0, \"bbox\": [252.0, 115.0, 120.0, 177.0], \"iscrowd\": 0}, {\"id\": 9, \"image_id\": 2, \"category_id\": 9, \"segmentation\": [[309.7054009819968, 242.94844517184941, 282.7054009819968, 251.94844517184941, 271.7054009819968, 287.9484451718494, 175.70540098199677, 275.9484451718494, 149.70540098199677, 296.9484451718494, 151.70540098199677, 319.9484451718494, 160.70540098199677, 328.9484451718494, 165.54250204582655, 375.38461538461536, 486.7054009819968, 373.9484451718494, 498.7054009819968, 336.9484451718494, 498.7054009819968, 202.94844517184941, 454.7054009819968, 193.94844517184941, 435.7054009819968, 212.94844517184941, 368.7054009819968, 224.94844517184941, 351.7054009819968, 241.94844517184941]], \"area\": 44532.0, \"bbox\": [149.0, 193.0, 350.0, 182.0], \"iscrowd\": 0}, {\"id\": 10, \"image_id\": 2, \"category_id\": 15, \"segmentation\": [[425.936170212766, 82.56382978723406, 404.936170212766, 109.56382978723406, 400.936170212766, 114.56382978723406, 437.936170212766, 114.56382978723406, 448.936170212766, 102.56382978723406, 446.936170212766, 91.56382978723406]], \"area\": 996.0, \"bbox\": [400.0, 82.0, 49.0, 33.0], \"iscrowd\": 0}, {\"id\": 11, \"image_id\": 2, \"category_id\": 18, \"segmentation\": [[183.936170212766, 140.56382978723406, 125.93617021276599, 140.56382978723406, 110.93617021276599, 187.56382978723406, 22.936170212765987, 199.56382978723406, 18.936170212765987, 218.56382978723406, 22.936170212765987, 234.56382978723406, 93.93617021276599, 239.56382978723406, 91.93617021276599, 229.56382978723406, 110.93617021276599, 203.56382978723406], [103.93617021276599, 290.56382978723406, 58.93617021276599, 303.56382978723406, 97.93617021276599, 311.56382978723406], [348.936170212766, 146.56382978723406, 472.936170212766, 149.56382978723406, 477.936170212766, 162.56382978723406, 471.936170212766, 196.56382978723406, 453.936170212766, 192.56382978723406, 434.936170212766, 213.56382978723406, 368.936170212766, 226.56382978723406, 375.936170212766, 187.56382978723406, 353.936170212766, 164.56382978723406], [246.936170212766, 252.56382978723406, 219.936170212766, 277.56382978723406, 254.936170212766, 287.56382978723406, 261.936170212766, 256.56382978723406]], \"area\": 14001.0, \"bbox\": [18.0, 140.0, 460.0, 172.0], \"iscrowd\": 0}], \"categories\": [{\"supercategory\": null, \"id\": 0, \"name\": \"_background_\"}, {\"supercategory\": null, \"id\": 1, \"name\": \"aeroplane\"}, {\"supercategory\": null, \"id\": 2, \"name\": \"bicycle\"}, {\"supercategory\": null, \"id\": 3, \"name\": \"bird\"}, {\"supercategory\": null, \"id\": 4, \"name\": \"boat\"}, {\"supercategory\": null, \"id\": 5, \"name\": \"bottle\"}, {\"supercategory\": null, \"id\": 6, \"name\": \"bus\"}, {\"supercategory\": null, \"id\": 7, \"name\": \"car\"}, {\"supercategory\": null, \"id\": 8, \"name\": \"cat\"}, {\"supercategory\": null, \"id\": 9, \"name\": \"chair\"}, {\"supercategory\": null, \"id\": 10, \"name\": \"cow\"}, {\"supercategory\": null, \"id\": 11, \"name\": \"diningtable\"}, {\"supercategory\": null, \"id\": 12, \"name\": \"dog\"}, {\"supercategory\": null, \"id\": 13, \"name\": \"horse\"}, {\"supercategory\": null, \"id\": 14, \"name\": \"motorbike\"}, {\"supercategory\": null, \"id\": 15, \"name\": \"person\"}, {\"supercategory\": null, \"id\": 16, \"name\": \"potted plant\"}, {\"supercategory\": null, \"id\": 17, \"name\": \"sheep\"}, {\"supercategory\": null, \"id\": 18, \"name\": \"sofa\"}, {\"supercategory\": null, \"id\": 19, \"name\": \"train\"}, {\"supercategory\": null, \"id\": 20, \"name\": \"tv/monitor\"}]}"
  },
  {
    "path": "examples/instance_segmentation/data_dataset_voc/class_names.txt",
    "content": "_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/instance_segmentation/labelme2coco.py",
    "content": "#!/usr/bin/env python\n\nimport argparse\nimport collections\nimport datetime\nimport glob\nimport json\nimport os\nimport os.path as osp\nimport sys\nimport uuid\n\nimport imgviz\nimport numpy as np\n\nimport labelme\n\ntry:\n    import pycocotools.mask  # type: ignore\nexcept ImportError:\n    print(\"Please install pycocotools:\\n\\n    pip install pycocotools\\n\")\n    sys.exit(1)\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"input_dir\", help=\"input annotated directory\")\n    parser.add_argument(\"output_dir\", help=\"output dataset directory\")\n    parser.add_argument(\"--labels\", help=\"labels file\", required=True)\n    parser.add_argument(\"--noviz\", help=\"no visualization\", action=\"store_true\")\n    args = parser.parse_args()\n\n    if osp.exists(args.output_dir):\n        print(\"Output directory already exists:\", args.output_dir)\n        sys.exit(1)\n    os.makedirs(args.output_dir)\n    os.makedirs(osp.join(args.output_dir, \"JPEGImages\"))\n    if not args.noviz:\n        os.makedirs(osp.join(args.output_dir, \"Visualization\"))\n    print(\"Creating dataset:\", args.output_dir)\n\n    now = datetime.datetime.now()\n\n    data = dict(\n        info=dict(\n            description=None,\n            url=None,\n            version=None,\n            year=now.year,\n            contributor=None,\n            date_created=now.strftime(\"%Y-%m-%d %H:%M:%S.%f\"),\n        ),\n        licenses=[\n            dict(\n                url=None,\n                id=0,\n                name=None,\n            )\n        ],\n        type=\"instances\",\n    )\n    data[\"images\"] = []  # license, url, file_name, height, width, date_captured, id\n    data[\"categories\"] = []  # supercategory, id, name\n    data[\n        \"annotations\"\n    ] = []  # segmentation, area, iscrowd, image_id, bbox, category_id, id\n\n    class_name_to_id = {}\n    for i, line in enumerate(open(args.labels).readlines()):\n        class_id = i - 1  # starts with -1\n        class_name = line.strip()\n        if class_id == -1:\n            assert class_name == \"__ignore__\"\n            continue\n        class_name_to_id[class_name] = class_id\n        data[\"categories\"].append(\n            dict(\n                supercategory=None,\n                id=class_id,\n                name=class_name,\n            )\n        )\n\n    out_ann_file = osp.join(args.output_dir, \"annotations.json\")\n    label_files = glob.glob(osp.join(args.input_dir, \"*.json\"))\n    for image_id, filename in enumerate(label_files):\n        print(\"Generating dataset from:\", filename)\n\n        label_file = labelme.LabelFile(filename=filename)\n\n        base = osp.splitext(osp.basename(filename))[0]\n        out_img_file = osp.join(args.output_dir, \"JPEGImages\", f\"{base}.jpg\")\n\n        img = labelme.utils.img_data_to_arr(label_file.imageData)\n        if img.ndim == 3 and img.shape[2] == 4:\n            img = imgviz.rgba2rgb(img)\n        imgviz.io.imsave(out_img_file, img)\n        data[\"images\"].append(\n            dict(\n                license=0,\n                url=None,\n                file_name=osp.relpath(out_img_file, osp.dirname(out_ann_file)),\n                height=img.shape[0],\n                width=img.shape[1],\n                date_captured=None,\n                id=image_id,\n            )\n        )\n\n        masks = {}  # for area\n        segmentations = collections.defaultdict(list)  # for segmentation\n        for shape in label_file.shapes:\n            points: list[list[int | float]] = shape[\"points\"]\n            label = shape[\"label\"]\n            group_id = shape.get(\"group_id\")\n            shape_type = shape.get(\"shape_type\", \"polygon\")\n            mask = labelme.utils.shape_to_mask(img.shape[:2], points, shape_type)\n\n            if group_id is None:\n                group_id = uuid.uuid1()\n\n            instance = (label, group_id)\n\n            if instance in masks:\n                masks[instance] = masks[instance] | mask\n            else:\n                masks[instance] = mask\n\n            points_coco: list[int | float]\n            if shape_type == \"rectangle\":\n                (x1, y1), (x2, y2) = points\n                x1, x2 = sorted([x1, x2])\n                y1, y2 = sorted([y1, y2])\n                points_coco = [x1, y1, x2, y1, x2, y2, x1, y2]\n            if shape_type == \"circle\":\n                (x1, y1), (x2, y2) = points\n                r = np.linalg.norm([x2 - x1, y2 - y1])\n                # r(1-cos(a/2))<x, a=2*pi/N => N>pi/arccos(1-x/r)\n                # x: tolerance of the gap between the arc and the line segment\n                n_points_circle = max(int(np.pi / np.arccos(1 - 1 / r)), 12)\n                i = np.arange(n_points_circle)\n                x = x1 + r * np.sin(2 * np.pi / n_points_circle * i)\n                y = y1 + r * np.cos(2 * np.pi / n_points_circle * i)\n                points_coco = np.stack((x, y), axis=1).flatten().tolist()\n            else:\n                points_coco = np.asarray(points).flatten().tolist()\n\n            segmentations[instance].append(points_coco)\n        segmentations = dict(segmentations)\n\n        for instance, mask in masks.items():\n            cls_name, group_id = instance\n            if cls_name not in class_name_to_id:\n                continue\n            cls_id = class_name_to_id[cls_name]\n\n            mask = np.asfortranarray(mask.astype(np.uint8))\n            mask = pycocotools.mask.encode(mask)\n            area = float(pycocotools.mask.area(mask))\n            bbox = pycocotools.mask.toBbox(mask).flatten().tolist()\n\n            data[\"annotations\"].append(\n                dict(\n                    id=len(data[\"annotations\"]),\n                    image_id=image_id,\n                    category_id=cls_id,\n                    segmentation=segmentations[instance],\n                    area=area,\n                    bbox=bbox,\n                    iscrowd=0,\n                )\n            )\n\n        if not args.noviz:\n            viz = img\n            if masks:\n                labels, captions, masks = zip(\n                    *[\n                        (class_name_to_id[cnm], cnm, msk)\n                        for (cnm, gid), msk in masks.items()\n                        if cnm in class_name_to_id\n                    ]\n                )\n                viz = imgviz.instances2rgb(\n                    image=img,\n                    labels=labels,\n                    masks=masks,\n                    captions=captions,\n                    font_size=15,\n                    line_width=2,\n                )\n            out_viz_file = osp.join(args.output_dir, \"Visualization\", f\"{base}.jpg\")\n            imgviz.io.imsave(out_viz_file, viz)\n\n    with open(out_ann_file, \"w\") as f:\n        json.dump(data, f)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/instance_segmentation/labelme2voc.py",
    "content": "#!/usr/bin/env python\n\n\nimport argparse\nimport glob\nimport os\nimport os.path as osp\nimport sys\n\nimport imgviz\nimport numpy as np\n\nimport labelme\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"input_dir\", help=\"Input annotated directory\")\n    parser.add_argument(\"output_dir\", help=\"Output dataset directory\")\n    parser.add_argument(\n        \"--labels\", help=\"Labels file or comma separated text\", required=True\n    )\n    parser.add_argument(\n        \"--noobject\", help=\"Flag not to generate object label\", action=\"store_true\"\n    )\n    parser.add_argument(\n        \"--nonpy\", help=\"Flag not to generate .npy files\", action=\"store_true\"\n    )\n    parser.add_argument(\n        \"--noviz\", help=\"Flag to disable visualization\", action=\"store_true\"\n    )\n    args = parser.parse_args()\n\n    if osp.exists(args.output_dir):\n        print(\"Output directory already exists:\", args.output_dir)\n        sys.exit(1)\n    os.makedirs(args.output_dir)\n    os.makedirs(osp.join(args.output_dir, \"JPEGImages\"))\n    os.makedirs(osp.join(args.output_dir, \"SegmentationClass\"))\n    if not args.nonpy:\n        os.makedirs(osp.join(args.output_dir, \"SegmentationClassNpy\"))\n    if not args.noviz:\n        os.makedirs(osp.join(args.output_dir, \"SegmentationClassVisualization\"))\n    if not args.noobject:\n        os.makedirs(osp.join(args.output_dir, \"SegmentationObject\"))\n        if not args.nonpy:\n            os.makedirs(osp.join(args.output_dir, \"SegmentationObjectNpy\"))\n        if not args.noviz:\n            os.makedirs(osp.join(args.output_dir, \"SegmentationObjectVisualization\"))\n    print(\"Creating dataset:\", args.output_dir)\n\n    if osp.exists(args.labels):\n        with open(args.labels) as f:\n            labels = [label.strip() for label in f if label]\n    else:\n        labels = [label.strip() for label in args.labels.split(\",\")]\n\n    class_names: list[str] = []\n    class_name_to_id = {}\n    for i, label in enumerate(labels):\n        class_id = i - 1  # starts with -1\n        class_name = label.strip()\n        class_name_to_id[class_name] = class_id\n        if class_id == -1:\n            assert class_name == \"__ignore__\"\n            continue\n        elif class_id == 0:\n            assert class_name == \"_background_\"\n        class_names.append(class_name)\n    print(\"class_names:\", class_names)\n    out_class_names_file = osp.join(args.output_dir, \"class_names.txt\")\n    with open(out_class_names_file, \"w\") as f:\n        f.writelines(\"\\n\".join(class_names))\n    print(\"Saved class_names:\", out_class_names_file)\n\n    for filename in sorted(glob.glob(osp.join(args.input_dir, \"*.json\"))):\n        print(\"Generating dataset from:\", filename)\n\n        label_file = labelme.LabelFile(filename=filename)\n\n        base = osp.splitext(osp.basename(filename))[0]\n        out_img_file = osp.join(args.output_dir, \"JPEGImages\", f\"{base}.jpg\")\n        out_clsp_file = osp.join(args.output_dir, \"SegmentationClass\", f\"{base}.png\")\n        if not args.nonpy:\n            out_cls_file = osp.join(\n                args.output_dir, \"SegmentationClassNpy\", f\"{base}.npy\"\n            )\n        if not args.noviz:\n            out_clsv_file = osp.join(\n                args.output_dir,\n                \"SegmentationClassVisualization\",\n                f\"{base}.jpg\",\n            )\n        if not args.noobject:\n            out_insp_file = osp.join(\n                args.output_dir, \"SegmentationObject\", f\"{base}.png\"\n            )\n            if not args.nonpy:\n                out_ins_file = osp.join(\n                    args.output_dir, \"SegmentationObjectNpy\", f\"{base}.npy\"\n                )\n            if not args.noviz:\n                out_insv_file = osp.join(\n                    args.output_dir,\n                    \"SegmentationObjectVisualization\",\n                    f\"{base}.jpg\",\n                )\n\n        img = labelme.utils.img_data_to_arr(label_file.imageData)\n        imgviz.io.imsave(out_img_file, img)\n\n        cls, ins = labelme.utils.shapes_to_label(\n            img_shape=img.shape,\n            shapes=label_file.shapes,\n            label_name_to_value=class_name_to_id,\n        )\n        ins[cls == -1] = 0  # ignore it.\n\n        # class label\n        labelme.utils.lblsave(out_clsp_file, cls)\n        if not args.nonpy:\n            np.save(out_cls_file, cls)\n        if not args.noviz:\n            clsv = imgviz.label2rgb(\n                cls,\n                imgviz.rgb2gray(img),\n                label_names=class_names,\n                font_size=15,\n                loc=\"rb\",\n            )\n            imgviz.io.imsave(out_clsv_file, clsv)\n\n        if not args.noobject:\n            # instance label\n            labelme.utils.lblsave(out_insp_file, ins)\n            if not args.nonpy:\n                np.save(out_ins_file, ins)\n            if not args.noviz:\n                instance_ids = np.unique(ins)\n                instance_names = [str(i) for i in range(max(instance_ids) + 1)]\n                insv = imgviz.label2rgb(\n                    ins,\n                    imgviz.rgb2gray(img),\n                    label_names=instance_names,\n                    font_size=15,\n                    loc=\"rb\",\n                )\n                imgviz.io.imsave(out_insv_file, insv)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/instance_segmentation/labels.txt",
    "content": "__ignore__\n_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/primitives/primitives.json",
    "content": "{\n  \"version\": \"5.7.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"rectangle\",\n      \"points\": [\n        [\n          32.0,\n          35.0\n        ],\n        [\n          132.0,\n          135.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"circle\",\n      \"points\": [\n        [\n          195.0,\n          84.0\n        ],\n        [\n          225.0,\n          125.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"circle\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"rectangle\",\n      \"points\": [\n        [\n          391.0,\n          33.0\n        ],\n        [\n          542.0,\n          135.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"rectangle\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"polygon\",\n      \"points\": [\n        [\n          69.0,\n          318.0\n        ],\n        [\n          45.0,\n          403.0\n        ],\n        [\n          173.0,\n          406.0\n        ],\n        [\n          198.0,\n          321.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"line\",\n      \"points\": [\n        [\n          188.0,\n          178.0\n        ],\n        [\n          160.0,\n          224.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"line\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"point\",\n      \"points\": [\n        [\n          345.0,\n          174.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"point\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"line_strip\",\n      \"points\": [\n        [\n          440.53703703703707,\n          181.46296296296293\n        ],\n        [\n          402.53703703703707,\n          274.46296296296293\n        ],\n        [\n          544.5370370370371,\n          275.46296296296293\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": null,\n      \"shape_type\": \"linestrip\",\n      \"flags\": {},\n      \"mask\": null\n    },\n    {\n      \"label\": \"octagon\",\n      \"points\": [\n        [\n          417.39759036144574,\n          305.0\n        ],\n        [\n          516.3975903614457,\n          404.0\n        ]\n      ],\n      \"group_id\": null,\n      \"description\": \"\",\n      \"shape_type\": \"mask\",\n      \"flags\": {},\n      \"mask\": \"iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAAAAABVicqIAAABd0lEQVR4nN3aUYrDMAwE0Bnd/86zdMt2aWI7TqwRJPooFGS9SE5DwSHOBV8furLoQq48CDfflY6005SJ9JOUhBxlaB2Z6VRryPRtoatlztzdGDLMIcYMk4Shw0SiyzCV6DBMJppM5BvgGEkxsCuz6QQWJUZXkBXhKcsuktkIe0hqsI24dgS+TtpIdiNsIcYIX2nuEd+2wzoubhFnI7BuPL8RayO4+y2Mz4CiYFowj4v/iLkRPGDj8R5SFEwLVeOiFeBTNh6vVsK/7SgaF+0En7LxeBDCCkSPGRdCFQjsoapbWGZBdT9GVSDeUOWzS8b6+kPsER/OjfhCv5+FT2FVIK7QF6L7dqINort2ogoEO8Q5r/CVVgPRHTtRE9H9OlEHsbUSrsJdJLEVdRFXRN9fCQ0Qj4ENktOK7CemODzMzGhGc9dN+wHzgiP3mwU4feh/ntFCnUlGq1XofqVkJkerBQ6ztLZ8JlELaydTdXnldLL1zzMvPAt+AJy8O66XXMiCAAAAAElFTkSuQmCC\"\n    }\n  ],\n  \"imagePath\": \"primitives.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 450,\n  \"imageWidth\": 560\n}"
  },
  {
    "path": "examples/semantic_segmentation/README.md",
    "content": "# Semantic Segmentation Example\n\n## Annotation\n\n```bash\nlabelme data_annotated --labels labels.txt --validatelabel exact --config '{shift_auto_shape_color: -2}'\n```\n\n![](.readme/annotation.jpg)\n\n\n## Convert to VOC-format Dataset\n\n```bash\n# It generates:\n#   - data_dataset_voc/JPEGImages\n#   - data_dataset_voc/SegmentationClass\n#   - data_dataset_voc/SegmentationClassNpy\n#   - data_dataset_voc/SegmentationClassVisualization\n./labelme2voc.py data_annotated data_dataset_voc --labels labels.txt --noobject\n```\n\n<img src=\"data_dataset_voc/JPEGImages/2011_000003.jpg\" width=\"33%\" /> <img src=\"data_dataset_voc/SegmentationClass/2011_000003.png\" width=\"33%\" /> <img src=\"data_dataset_voc/SegmentationClassVisualization/2011_000003.jpg\" width=\"33%\" />\n\nFig 1. JPEG image (left), PNG label (center), JPEG label visualization (right)  \n\n\nNote that the label file contains only very low label values (ex. `0, 4, 14`), and\n`255` indicates the `__ignore__` label value (`-1` in the npy file).  \nYou can see the label PNG file by following.\n\n```bash\n../tutorial/draw_label_png.py data_dataset_voc/SegmentationClass/2011_000003.png\n```\n\n<img src=\".readme/draw_label_png.jpg\" width=\"33%\" />\n"
  },
  {
    "path": "examples/semantic_segmentation/data_annotated/2011_000003.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          250.8142292490119,\n          106.96696468940974\n        ],\n        [\n          229.8142292490119,\n          118.96696468940974\n        ],\n        [\n          221.8142292490119,\n          134.96696468940974\n        ],\n        [\n          223.8142292490119,\n          147.96696468940974\n        ],\n        [\n          217.8142292490119,\n          160.96696468940974\n        ],\n        [\n          202.8142292490119,\n          167.96696468940974\n        ],\n        [\n          192.8142292490119,\n          199.96696468940974\n        ],\n        [\n          194.8142292490119,\n          221.96696468940974\n        ],\n        [\n          199.8142292490119,\n          226.96696468940974\n        ],\n        [\n          191.8142292490119,\n          233.96696468940974\n        ],\n        [\n          197.8142292490119,\n          263.9669646894098\n        ],\n        [\n          213.8142292490119,\n          294.9669646894098\n        ],\n        [\n          214.8142292490119,\n          319.9669646894098\n        ],\n        [\n          221.8142292490119,\n          326.9669646894098\n        ],\n        [\n          235.8142292490119,\n          325.9669646894098\n        ],\n        [\n          240.8142292490119,\n          322.9669646894098\n        ],\n        [\n          235.8142292490119,\n          297.9669646894098\n        ],\n        [\n          238.8142292490119,\n          286.9669646894098\n        ],\n        [\n          234.8142292490119,\n          267.9669646894098\n        ],\n        [\n          257.81422924901193,\n          257.9669646894098\n        ],\n        [\n          264.81422924901193,\n          263.9669646894098\n        ],\n        [\n          256.81422924901193,\n          272.9669646894098\n        ],\n        [\n          259.81422924901193,\n          281.9669646894098\n        ],\n        [\n          284.81422924901193,\n          287.9669646894098\n        ],\n        [\n          297.81422924901193,\n          277.9669646894098\n        ],\n        [\n          288.81422924901193,\n          269.9669646894098\n        ],\n        [\n          281.81422924901193,\n          269.9669646894098\n        ],\n        [\n          283.81422924901193,\n          263.9669646894098\n        ],\n        [\n          292.81422924901193,\n          260.9669646894098\n        ],\n        [\n          308.81422924901193,\n          235.96696468940974\n        ],\n        [\n          313.81422924901193,\n          216.96696468940974\n        ],\n        [\n          309.81422924901193,\n          207.96696468940974\n        ],\n        [\n          312.81422924901193,\n          201.96696468940974\n        ],\n        [\n          308.81422924901193,\n          184.96696468940974\n        ],\n        [\n          291.81422924901193,\n          172.96696468940974\n        ],\n        [\n          269.81422924901193,\n          158.96696468940974\n        ],\n        [\n          261.81422924901193,\n          153.96696468940974\n        ],\n        [\n          264.81422924901193,\n          141.96696468940974\n        ],\n        [\n          273.81422924901193,\n          136.96696468940974\n        ],\n        [\n          278.81422924901193,\n          129.96696468940974\n        ],\n        [\n          270.81422924901193,\n          120.96696468940974\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          482.81422924901193,\n          85.33596837944665\n        ],\n        [\n          468.81422924901193,\n          90.33596837944665\n        ],\n        [\n          460.81422924901193,\n          110.33596837944665\n        ],\n        [\n          460.81422924901193,\n          127.33596837944665\n        ],\n        [\n          444.81422924901193,\n          137.33596837944665\n        ],\n        [\n          419.81422924901193,\n          153.33596837944665\n        ],\n        [\n          410.81422924901193,\n          163.33596837944665\n        ],\n        [\n          403.81422924901193,\n          168.33596837944665\n        ],\n        [\n          394.81422924901193,\n          170.33596837944665\n        ],\n        [\n          386.81422924901193,\n          168.33596837944665\n        ],\n        [\n          386.81422924901193,\n          184.33596837944665\n        ],\n        [\n          392.81422924901193,\n          182.33596837944665\n        ],\n        [\n          410.81422924901193,\n          187.33596837944665\n        ],\n        [\n          414.81422924901193,\n          192.33596837944665\n        ],\n        [\n          437.81422924901193,\n          189.33596837944665\n        ],\n        [\n          434.81422924901193,\n          204.33596837944665\n        ],\n        [\n          390.81422924901193,\n          195.33596837944665\n        ],\n        [\n          386.81422924901193,\n          195.33596837944665\n        ],\n        [\n          387.81422924901193,\n          208.33596837944665\n        ],\n        [\n          381.81422924901193,\n          212.33596837944665\n        ],\n        [\n          372.81422924901193,\n          212.33596837944665\n        ],\n        [\n          372.81422924901193,\n          216.33596837944665\n        ],\n        [\n          400.81422924901193,\n          270.3359683794467\n        ],\n        [\n          389.81422924901193,\n          272.3359683794467\n        ],\n        [\n          389.81422924901193,\n          274.3359683794467\n        ],\n        [\n          403.81422924901193,\n          282.3359683794467\n        ],\n        [\n          444.81422924901193,\n          283.3359683794467\n        ],\n        [\n          443.81422924901193,\n          259.3359683794467\n        ],\n        [\n          426.81422924901193,\n          244.33596837944665\n        ],\n        [\n          462.81422924901193,\n          256.3359683794467\n        ],\n        [\n          474.81422924901193,\n          270.3359683794467\n        ],\n        [\n          477.81422924901193,\n          280.3359683794467\n        ],\n        [\n          473.81422924901193,\n          289.3359683794467\n        ],\n        [\n          471.81422924901193,\n          296.3359683794467\n        ],\n        [\n          472.81422924901193,\n          317.3359683794467\n        ],\n        [\n          480.81422924901193,\n          332.3359683794467\n        ],\n        [\n          494.81422924901193,\n          335.3359683794467\n        ],\n        [\n          498.81422924901193,\n          329.3359683794467\n        ],\n        [\n          494.81422924901193,\n          308.3359683794467\n        ],\n        [\n          499.81422924901193,\n          297.3359683794467\n        ],\n        [\n          499.81422924901193,\n          90.33596837944665\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          370.81422924901193,\n          170.33596837944665\n        ],\n        [\n          366.81422924901193,\n          173.33596837944665\n        ],\n        [\n          365.81422924901193,\n          182.33596837944665\n        ],\n        [\n          368.81422924901193,\n          185.33596837944665\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"bottle\",\n      \"points\": [\n        [\n          374.81422924901193,\n          159.33596837944665\n        ],\n        [\n          369.81422924901193,\n          170.33596837944665\n        ],\n        [\n          369.81422924901193,\n          210.33596837944665\n        ],\n        [\n          375.81422924901193,\n          212.33596837944665\n        ],\n        [\n          387.81422924901193,\n          209.33596837944665\n        ],\n        [\n          385.81422924901193,\n          185.33596837944665\n        ],\n        [\n          385.81422924901193,\n          168.33596837944665\n        ],\n        [\n          385.81422924901193,\n          165.33596837944665\n        ],\n        [\n          382.81422924901193,\n          159.33596837944665\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"__ignore__\",\n      \"points\": [\n        [\n          338.81422924901193,\n          266.3359683794467\n        ],\n        [\n          313.81422924901193,\n          269.3359683794467\n        ],\n        [\n          297.81422924901193,\n          277.3359683794467\n        ],\n        [\n          282.81422924901193,\n          288.3359683794467\n        ],\n        [\n          273.81422924901193,\n          302.3359683794467\n        ],\n        [\n          272.81422924901193,\n          320.3359683794467\n        ],\n        [\n          279.81422924901193,\n          337.3359683794467\n        ],\n        [\n          428.81422924901193,\n          337.3359683794467\n        ],\n        [\n          432.81422924901193,\n          316.3359683794467\n        ],\n        [\n          423.81422924901193,\n          296.3359683794467\n        ],\n        [\n          403.81422924901193,\n          283.3359683794467\n        ],\n        [\n          370.81422924901193,\n          270.3359683794467\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000003.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 338,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/semantic_segmentation/data_annotated/2011_000006.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          204.936170212766,\n          108.56382978723406\n        ],\n        [\n          183.936170212766,\n          141.56382978723406\n        ],\n        [\n          166.936170212766,\n          150.56382978723406\n        ],\n        [\n          108.93617021276599,\n          203.56382978723406\n        ],\n        [\n          92.93617021276599,\n          228.56382978723406\n        ],\n        [\n          95.93617021276599,\n          244.56382978723406\n        ],\n        [\n          105.93617021276599,\n          244.56382978723406\n        ],\n        [\n          116.93617021276599,\n          223.56382978723406\n        ],\n        [\n          163.936170212766,\n          187.56382978723406\n        ],\n        [\n          147.936170212766,\n          212.56382978723406\n        ],\n        [\n          117.93617021276599,\n          222.56382978723406\n        ],\n        [\n          108.93617021276599,\n          243.56382978723406\n        ],\n        [\n          100.93617021276599,\n          325.56382978723406\n        ],\n        [\n          135.936170212766,\n          329.56382978723406\n        ],\n        [\n          148.936170212766,\n          319.56382978723406\n        ],\n        [\n          150.936170212766,\n          295.56382978723406\n        ],\n        [\n          169.936170212766,\n          272.56382978723406\n        ],\n        [\n          171.936170212766,\n          249.56382978723406\n        ],\n        [\n          178.936170212766,\n          246.56382978723406\n        ],\n        [\n          186.936170212766,\n          225.56382978723406\n        ],\n        [\n          214.936170212766,\n          219.56382978723406\n        ],\n        [\n          242.936170212766,\n          157.56382978723406\n        ],\n        [\n          228.936170212766,\n          146.56382978723406\n        ],\n        [\n          228.936170212766,\n          125.56382978723406\n        ],\n        [\n          216.936170212766,\n          112.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          271.936170212766,\n          109.56382978723406\n        ],\n        [\n          249.936170212766,\n          110.56382978723406\n        ],\n        [\n          244.936170212766,\n          150.56382978723406\n        ],\n        [\n          215.936170212766,\n          219.56382978723406\n        ],\n        [\n          208.936170212766,\n          245.56382978723406\n        ],\n        [\n          214.936170212766,\n          220.56382978723406\n        ],\n        [\n          188.936170212766,\n          227.56382978723406\n        ],\n        [\n          170.936170212766,\n          246.56382978723406\n        ],\n        [\n          170.936170212766,\n          275.56382978723406\n        ],\n        [\n          221.936170212766,\n          278.56382978723406\n        ],\n        [\n          233.936170212766,\n          259.56382978723406\n        ],\n        [\n          246.936170212766,\n          253.56382978723406\n        ],\n        [\n          245.936170212766,\n          256.56382978723406\n        ],\n        [\n          242.936170212766,\n          251.56382978723406\n        ],\n        [\n          262.936170212766,\n          256.56382978723406\n        ],\n        [\n          304.936170212766,\n          226.56382978723406\n        ],\n        [\n          297.936170212766,\n          199.56382978723406\n        ],\n        [\n          308.936170212766,\n          164.56382978723406\n        ],\n        [\n          296.936170212766,\n          148.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          308.936170212766,\n          115.56382978723406\n        ],\n        [\n          298.936170212766,\n          145.56382978723406\n        ],\n        [\n          309.936170212766,\n          166.56382978723406\n        ],\n        [\n          297.936170212766,\n          200.56382978723406\n        ],\n        [\n          305.936170212766,\n          228.56382978723406\n        ],\n        [\n          262.936170212766,\n          258.56382978723406\n        ],\n        [\n          252.936170212766,\n          284.56382978723406\n        ],\n        [\n          272.936170212766,\n          291.56382978723406\n        ],\n        [\n          281.936170212766,\n          250.56382978723406\n        ],\n        [\n          326.936170212766,\n          235.56382978723406\n        ],\n        [\n          351.936170212766,\n          239.56382978723406\n        ],\n        [\n          365.936170212766,\n          223.56382978723406\n        ],\n        [\n          371.936170212766,\n          187.56382978723406\n        ],\n        [\n          353.936170212766,\n          168.56382978723406\n        ],\n        [\n          344.936170212766,\n          143.56382978723406\n        ],\n        [\n          336.936170212766,\n          115.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"chair\",\n      \"points\": [\n        [\n          308.936170212766,\n          243.33306055646483\n        ],\n        [\n          281.936170212766,\n          252.33306055646483\n        ],\n        [\n          270.936170212766,\n          288.33306055646483\n        ],\n        [\n          174.936170212766,\n          276.33306055646483\n        ],\n        [\n          148.936170212766,\n          297.33306055646483\n        ],\n        [\n          150.936170212766,\n          320.33306055646483\n        ],\n        [\n          159.936170212766,\n          329.33306055646483\n        ],\n        [\n          164.77327127659578,\n          375.7692307692308\n        ],\n        [\n          485.936170212766,\n          374.33306055646483\n        ],\n        [\n          497.936170212766,\n          337.33306055646483\n        ],\n        [\n          497.936170212766,\n          203.33306055646483\n        ],\n        [\n          453.936170212766,\n          194.33306055646483\n        ],\n        [\n          434.936170212766,\n          213.33306055646483\n        ],\n        [\n          367.936170212766,\n          225.33306055646483\n        ],\n        [\n          350.936170212766,\n          242.33306055646483\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"person\",\n      \"points\": [\n        [\n          425.936170212766,\n          82.56382978723406\n        ],\n        [\n          404.936170212766,\n          109.56382978723406\n        ],\n        [\n          400.936170212766,\n          114.56382978723406\n        ],\n        [\n          437.936170212766,\n          114.56382978723406\n        ],\n        [\n          448.936170212766,\n          102.56382978723406\n        ],\n        [\n          446.936170212766,\n          91.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"__ignore__\",\n      \"points\": [\n        [\n          457.936170212766,\n          85.56382978723406\n        ],\n        [\n          439.936170212766,\n          117.56382978723406\n        ],\n        [\n          477.936170212766,\n          117.56382978723406\n        ],\n        [\n          474.936170212766,\n          87.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          183.936170212766,\n          140.56382978723406\n        ],\n        [\n          125.93617021276599,\n          140.56382978723406\n        ],\n        [\n          110.93617021276599,\n          187.56382978723406\n        ],\n        [\n          22.936170212765987,\n          199.56382978723406\n        ],\n        [\n          18.936170212765987,\n          218.56382978723406\n        ],\n        [\n          22.936170212765987,\n          234.56382978723406\n        ],\n        [\n          93.93617021276599,\n          239.56382978723406\n        ],\n        [\n          91.93617021276599,\n          229.56382978723406\n        ],\n        [\n          110.93617021276599,\n          203.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          103.93617021276599,\n          290.56382978723406\n        ],\n        [\n          58.93617021276599,\n          303.56382978723406\n        ],\n        [\n          97.93617021276599,\n          311.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          348.936170212766,\n          146.56382978723406\n        ],\n        [\n          472.936170212766,\n          149.56382978723406\n        ],\n        [\n          477.936170212766,\n          162.56382978723406\n        ],\n        [\n          471.936170212766,\n          196.56382978723406\n        ],\n        [\n          453.936170212766,\n          192.56382978723406\n        ],\n        [\n          434.936170212766,\n          213.56382978723406\n        ],\n        [\n          368.936170212766,\n          226.56382978723406\n        ],\n        [\n          375.936170212766,\n          187.56382978723406\n        ],\n        [\n          353.936170212766,\n          164.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"sofa\",\n      \"points\": [\n        [\n          246.936170212766,\n          252.56382978723406\n        ],\n        [\n          219.936170212766,\n          277.56382978723406\n        ],\n        [\n          254.936170212766,\n          287.56382978723406\n        ],\n        [\n          261.936170212766,\n          256.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000006.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/semantic_segmentation/data_annotated/2011_000025.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          260.936170212766,\n          22.948445171849443\n        ],\n        [\n          193.936170212766,\n          19.948445171849443\n        ],\n        [\n          124.93617021276599,\n          39.94844517184944\n        ],\n        [\n          89.93617021276599,\n          101.94844517184944\n        ],\n        [\n          81.93617021276599,\n          150.94844517184944\n        ],\n        [\n          108.93617021276599,\n          145.94844517184944\n        ],\n        [\n          88.93617021276599,\n          244.94844517184944\n        ],\n        [\n          89.93617021276599,\n          322.94844517184936\n        ],\n        [\n          116.93617021276599,\n          367.94844517184936\n        ],\n        [\n          158.936170212766,\n          368.94844517184936\n        ],\n        [\n          165.936170212766,\n          337.94844517184936\n        ],\n        [\n          347.936170212766,\n          335.94844517184936\n        ],\n        [\n          349.936170212766,\n          369.94844517184936\n        ],\n        [\n          391.936170212766,\n          373.94844517184936\n        ],\n        [\n          403.936170212766,\n          335.94844517184936\n        ],\n        [\n          425.936170212766,\n          332.94844517184936\n        ],\n        [\n          421.936170212766,\n          281.94844517184936\n        ],\n        [\n          428.936170212766,\n          252.94844517184944\n        ],\n        [\n          428.936170212766,\n          236.94844517184944\n        ],\n        [\n          409.936170212766,\n          220.94844517184944\n        ],\n        [\n          409.936170212766,\n          150.94844517184944\n        ],\n        [\n          430.936170212766,\n          143.94844517184944\n        ],\n        [\n          433.936170212766,\n          112.94844517184944\n        ],\n        [\n          431.936170212766,\n          96.94844517184944\n        ],\n        [\n          408.936170212766,\n          90.94844517184944\n        ],\n        [\n          395.936170212766,\n          50.94844517184944\n        ],\n        [\n          338.936170212766,\n          25.948445171849443\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"bus\",\n      \"points\": [\n        [\n          88.93617021276599,\n          115.56382978723406\n        ],\n        [\n          0.9361702127659877,\n          96.56382978723406\n        ],\n        [\n          0.0,\n          251.968085106388\n        ],\n        [\n          0.9361702127659877,\n          265.56382978723406\n        ],\n        [\n          27.936170212765987,\n          265.56382978723406\n        ],\n        [\n          29.936170212765987,\n          283.56382978723406\n        ],\n        [\n          63.93617021276599,\n          281.56382978723406\n        ],\n        [\n          89.93617021276599,\n          252.56382978723406\n        ],\n        [\n          100.93617021276599,\n          183.56382978723406\n        ],\n        [\n          108.93617021276599,\n          145.56382978723406\n        ],\n        [\n          81.93617021276599,\n          151.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          413.936170212766,\n          168.56382978723406\n        ],\n        [\n          497.936170212766,\n          168.56382978723406\n        ],\n        [\n          497.936170212766,\n          256.56382978723406\n        ],\n        [\n          431.936170212766,\n          258.56382978723406\n        ],\n        [\n          430.936170212766,\n          236.56382978723406\n        ],\n        [\n          408.936170212766,\n          218.56382978723406\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"2011_000025.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 375,\n  \"imageWidth\": 500\n}"
  },
  {
    "path": "examples/semantic_segmentation/data_dataset_voc/class_names.txt",
    "content": "_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/semantic_segmentation/labels.txt",
    "content": "__ignore__\n_background_\naeroplane\nbicycle\nbird\nboat\nbottle\nbus\ncar\ncat\nchair\ncow\ndiningtable\ndog\nhorse\nmotorbike\nperson\npotted plant\nsheep\nsofa\ntrain\ntv/monitor"
  },
  {
    "path": "examples/tutorial/README.md",
    "content": "# Tutorial (Single Image Example)\n\n## Annotation\n\n```bash\nlabelme apc2016_obj3.jpg\n```\n\n![](.readme/annotation.jpg)\n\n\n## Visualization\n\nTo view the json file quickly, you can use utility script:\n\n```bash\n./draw_json.py apc2016_obj3.json\n```\n\n<img src=\".readme/draw_json.jpg\" width=\"70%\" />\n\n\n## Convert to Dataset\n\nTo convert the json to set of image and label, you can run following:\n\n\n```bash\n./export_json.py apc2016_obj3.json\n```\n\nIt generates standard files from the JSON file.\n\n- [img.png](apc2016_obj3/img.png): Image file.\n- [label.png](apc2016_obj3/label.png): uint8 label file.\n- [label_viz.png](apc2016_obj3/label_viz.png): Visualization of `label.png`.\n- [label_names.txt](apc2016_obj3/label_names.txt): Label names for values in `label.png`.\n\n## How to load label PNG file?\n\nNote that loading `label.png` is a bit difficult\n(`scipy.misc.imread`, `skimage.io.imread` may not work correctly),\nand please use `PIL.Image.open` to avoid unexpected behavior:\n\n```python\n# see load_label_png.py also.\n>>> import numpy as np\n>>> import PIL.Image\n\n>>> label_png = 'apc2016_obj3/label.png'\n>>> lbl = np.asarray(PIL.Image.open(label_png))\n>>> print(lbl.dtype)\ndtype('uint8')\n>>> np.unique(lbl)\narray([0, 1, 2, 3], dtype=uint8)\n>>> lbl.shape\n(907, 1210)\n```\n\nAlso, you can see the label PNG file by:\n\n```bash\n./draw_label_png.py apc2016_obj3/label.png\n```\n\n<img src=\".readme/draw_label_png.jpg\" width=\"35%\" />\n"
  },
  {
    "path": "examples/tutorial/apc2016_obj3/label_names.txt",
    "content": "_background_\nhighland_6539_self_stick_notes\nkong_air_dog_squeakair_tennis_ball\nmead_index_cards\nshelf\n"
  },
  {
    "path": "examples/tutorial/apc2016_obj3.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"shelf\",\n      \"points\": [\n        [\n          7.942307692307736,\n          80.76150251617551\n        ],\n        [\n          171.94230769230774,\n          714.7615025161755\n        ],\n        [\n          968.9423076923077,\n          733.7615025161755\n        ],\n        [\n          1181.9423076923076,\n          110.76150251617551\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"highland_6539_self_stick_notes\",\n      \"points\": [\n        [\n          430.16339869281046,\n          516.2450980392157\n        ],\n        [\n          390.9477124183006,\n          606.4411764705883\n        ],\n        [\n          398.7908496732026,\n          697.2908496732026\n        ],\n        [\n          522.3202614379085,\n          711.6699346405229\n        ],\n        [\n          762.18954248366,\n          721.4738562091503\n        ],\n        [\n          777.2222222222222,\n          634.5457516339869\n        ],\n        [\n          761.5359477124183,\n          537.8137254901961\n        ],\n        [\n          634.0849673202614,\n          518.8594771241831\n        ],\n        [\n          573.3006535947712,\n          512.9771241830066\n        ],\n        [\n          534.0849673202614,\n          513.6307189542484\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"mead_index_cards\",\n      \"points\": [\n        [\n          447.156862745098,\n          394.6764705882353\n        ],\n        [\n          410.55555555555554,\n          480.95098039215685\n        ],\n        [\n          415.1307189542483,\n          522.781045751634\n        ],\n        [\n          422.9738562091503,\n          522.781045751634\n        ],\n        [\n          427.5490196078431,\n          515.5915032679738\n        ],\n        [\n          570.032679738562,\n          512.3235294117648\n        ],\n        [\n          732.1241830065359,\n          528.0098039215686\n        ],\n        [\n          733.4313725490196,\n          492.71568627450984\n        ],\n        [\n          724.9346405228757,\n          407.0947712418301\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"kong_air_dog_squeakair_tennis_ball\",\n      \"points\": [\n        [\n          419.05228758169926,\n          266.5718954248366\n        ],\n        [\n          343.235294117647,\n          303.1732026143791\n        ],\n        [\n          511.2091503267974,\n          318.859477124183\n        ],\n        [\n          519.7058823529411,\n          334.5457516339869\n        ],\n        [\n          533.4313725490196,\n          339.7745098039216\n        ],\n        [\n          551.7320261437908,\n          349.57843137254906\n        ],\n        [\n          573.3006535947712,\n          354.15359477124184\n        ],\n        [\n          592.2549019607843,\n          353.5\n        ],\n        [\n          604.0196078431372,\n          345.0032679738562\n        ],\n        [\n          613.1699346405228,\n          341.7352941176471\n        ],\n        [\n          687.0261437908497,\n          365.91830065359477\n        ],\n        [\n          696.1764705882352,\n          358.07516339869284\n        ],\n        [\n          727.5490196078431,\n          329.3169934640523\n        ],\n        [\n          677.2222222222222,\n          306.44117647058823\n        ],\n        [\n          651.078431372549,\n          273.76143790849676\n        ],\n        [\n          632.1241830065359,\n          272.4542483660131\n        ],\n        [\n          612.516339869281,\n          248.27124183006538\n        ],\n        [\n          596.8300653594771,\n          241.08169934640526\n        ],\n        [\n          577.2222222222222,\n          234.54575163398695\n        ],\n        [\n          563.4967320261437,\n          234.54575163398695\n        ],\n        [\n          545.1960784313725,\n          235.19934640522877\n        ],\n        [\n          534.7385620915032,\n          242.3888888888889\n        ],\n        [\n          526.2418300653594,\n          247.61764705882354\n        ],\n        [\n          513.1699346405228,\n          258.7287581699347\n        ],\n        [\n          507.28758169934633,\n          266.5718954248366\n        ],\n        [\n          502.0588235294117,\n          272.4542483660131\n        ],\n        [\n          496.17647058823525,\n          273.1078431372549\n        ],\n        [\n          474.6078431372549,\n          273.1078431372549\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"apc2016_obj3.json\",\n  \"imageData\": \"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\",\n  \"imageHeight\": 907,\n  \"imageWidth\": 1210\n}"
  },
  {
    "path": "examples/tutorial/draw_json.py",
    "content": "#!/usr/bin/env python\n\nimport argparse\n\nimport imgviz\nimport matplotlib.pyplot as plt\n\nfrom labelme import utils\nfrom labelme._label_file import LabelFile\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"json_file\")\n    args = parser.parse_args()\n\n    label_file = LabelFile(args.json_file)\n    img = utils.img_data_to_arr(label_file.imageData)\n\n    label_name_to_value = {\"_background_\": 0}\n    for shape in sorted(label_file.shapes, key=lambda x: x[\"label\"]):\n        label_name = shape[\"label\"]\n        if label_name in label_name_to_value:\n            label_value = label_name_to_value[label_name]\n        else:\n            label_value = len(label_name_to_value)\n            label_name_to_value[label_name] = label_value\n    lbl, _ = utils.shapes_to_label(img.shape, label_file.shapes, label_name_to_value)\n\n    label_names: list[str] = [\"\"] * (max(label_name_to_value.values()) + 1)\n    for name, value in label_name_to_value.items():\n        label_names[value] = name\n    lbl_viz = imgviz.label2rgb(\n        lbl,\n        imgviz.asgray(img),\n        label_names=label_names,\n        font_size=30,\n        loc=\"rb\",\n    )\n\n    plt.subplot(121)\n    plt.imshow(img)\n    plt.subplot(122)\n    plt.imshow(lbl_viz)\n    plt.show()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/tutorial/draw_label_png.py",
    "content": "#!/usr/bin/env python\n\nimport argparse\nimport os\n\nimport imgviz\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom loguru import logger\n\n\ndef main():\n    parser = argparse.ArgumentParser(\n        formatter_class=argparse.ArgumentDefaultsHelpFormatter\n    )\n    parser.add_argument(\"label_png\", help=\"label PNG file\")\n    parser.add_argument(\n        \"--labels\",\n        help=\"labels list (comma separated text or file)\",\n        default=None,\n    )\n    parser.add_argument(\"--image\", help=\"image file\", default=None)\n    args = parser.parse_args()\n\n    if args.labels is not None:\n        if os.path.exists(args.labels):\n            with open(args.labels) as f:\n                label_names = [label.strip() for label in f]\n        else:\n            label_names = args.labels.split(\",\")\n    else:\n        label_names = None\n\n    if args.image is not None:\n        image = imgviz.io.imread(args.image)\n    else:\n        image = None\n\n    label = imgviz.io.imread(args.label_png)\n    label = label.astype(np.int32)\n    label[label == 255] = -1\n\n    unique_label_values = np.unique(label)\n\n    logger.info(f\"Label image shape: {label.shape}\")\n    logger.info(f\"Label values: {unique_label_values.tolist()}\")\n    if label_names is not None:\n        logger.info(\n            \"Label names: {}\".format(\n                [\n                    f\"{label_value}:{label_names[label_value]}\"\n                    for label_value in unique_label_values\n                ]\n            )\n        )\n\n    if args.image:\n        num_cols = 2\n    else:\n        num_cols = 1\n\n    plt.figure(figsize=(num_cols * 6, 5))\n\n    plt.subplot(1, num_cols, 1)\n    plt.title(args.label_png)\n    label_viz = imgviz.label2rgb(\n        label=label, label_names=label_names, font_size=label.shape[1] // 30\n    )\n    plt.imshow(label_viz)\n\n    if image is not None:\n        plt.subplot(1, num_cols, 2)\n        label_viz_with_overlay = imgviz.label2rgb(\n            label=label,\n            image=image,\n            label_names=label_names,\n            font_size=label.shape[1] // 30,\n        )\n        plt.title(f\"{args.label_png}\\n{args.image}\")\n        plt.imshow(label_viz_with_overlay)\n\n    plt.tight_layout()\n    plt.show()\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/tutorial/export_json.py",
    "content": "#!/usr/bin/env python\n\nimport argparse\nimport os\nimport os.path as osp\n\nimport imgviz\nimport numpy as np\nimport PIL.Image\nfrom loguru import logger\nfrom numpy.typing import NDArray\n\nfrom labelme import utils\nfrom labelme._label_file import LabelFile\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"json_file\")\n    parser.add_argument(\"-o\", \"--out\", default=None)\n    args = parser.parse_args()\n\n    json_file = args.json_file\n\n    if args.out is None:\n        out_dir = osp.splitext(osp.basename(json_file))[0]\n        out_dir = osp.join(osp.dirname(json_file), out_dir)\n    else:\n        out_dir = args.out\n    os.makedirs(out_dir, exist_ok=True)\n\n    label_file: LabelFile = LabelFile(filename=json_file)\n\n    image: NDArray[np.uint8] = utils.img_data_to_arr(label_file.imageData)\n\n    label_name_to_value: dict[str, int] = {\"_background_\": 0}\n    for shape in sorted(label_file.shapes, key=lambda x: x[\"label\"]):\n        label_name = shape[\"label\"]\n        if label_name in label_name_to_value:\n            label_value = label_name_to_value[label_name]\n        else:\n            label_value = len(label_name_to_value)\n            label_name_to_value[label_name] = label_value\n    lbl, _ = utils.shapes_to_label(image.shape, label_file.shapes, label_name_to_value)\n\n    label_names: list[str] = [\"\"] * (max(label_name_to_value.values()) + 1)\n    for name, value in label_name_to_value.items():\n        label_names[value] = name\n\n    lbl_viz = imgviz.label2rgb(\n        lbl, imgviz.asgray(image), label_names=label_names, loc=\"rb\"\n    )\n\n    PIL.Image.fromarray(image).save(osp.join(out_dir, \"img.png\"))\n    utils.lblsave(osp.join(out_dir, \"label.png\"), lbl)\n    PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, \"label_viz.png\"))\n\n    with open(osp.join(out_dir, \"label_names.txt\"), \"w\") as f:\n        for lbl_name in label_names:\n            f.write(f\"{lbl_name}\\n\")\n\n    logger.info(f\"Saved to: {out_dir}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/tutorial/load_label_png.py",
    "content": "#!/usr/bin/env python\n\n\nimport os.path as osp\n\nimport numpy as np\nimport PIL.Image\n\nhere = osp.dirname(osp.abspath(__file__))\n\n\ndef main():\n    label_png = osp.join(here, \"apc2016_obj3/label.png\")\n    print(\"Loading:\", label_png)\n    print()\n\n    lbl = np.asarray(PIL.Image.open(label_png))\n    labels = np.unique(lbl)\n\n    label_names_txt = osp.join(here, \"apc2016_obj3/label_names.txt\")\n    label_names = [name.strip() for name in open(label_names_txt)]\n    print(\"# of labels:\", len(labels))\n    print(\"# of label_names:\", len(label_names))\n    if len(labels) != len(label_names):\n        print(\"Number of unique labels and label_names must be same.\")\n        quit(1)\n    print()\n\n    print(\"label: label_name\")\n    for label, label_name in zip(labels, label_names):\n        print(f\"{label}: {label_name}\")\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "examples/video_annotation/README.md",
    "content": "# Video Annotation Example\n\n\n## Annotation\n\n```bash\nlabelme data_annotated --labels labels.txt --keep-prev --config '{shift_auto_shape_color: -2}'\n```\n\n<img src=\".readme/00000100.jpg\" width=\"49%\" /> <img src=\".readme/00000101.jpg\" width=\"49%\" />\n\n*Fig 1. Video annotation example. A frame (left), The next frame (right).*\n\n\n<img src=\".readme/data_annotated.gif\" width=\"98%\" />\n\n*Fig 2. Visualization of video semantic segmentation.*\n\n\n## How to Convert a Video File to Images for Annotation?\n\n```bash\npip install video-cli\n\nvideo-toimg your_video.mp4  # this creates your_video/ directory\nls your_video/\n\nlabelme your_video/\n```\n"
  },
  {
    "path": "examples/video_annotation/data_annotated/00000100.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          634.0,\n          203.25925925925924\n        ],\n        [\n          604.0,\n          274.25925925925924\n        ],\n        [\n          603.0,\n          339.25925925925924\n        ],\n        [\n          622.0,\n          362.25925925925924\n        ],\n        [\n          639.0,\n          362.25925925925924\n        ],\n        [\n          649.0,\n          353.25925925925924\n        ],\n        [\n          682.0,\n          382.25925925925924\n        ],\n        [\n          733.0,\n          389.25925925925924\n        ],\n        [\n          748.0,\n          363.25925925925924\n        ],\n        [\n          827.0,\n          358.25925925925924\n        ],\n        [\n          829.0,\n          249.25925925925924\n        ],\n        [\n          800.0,\n          193.25925925925924\n        ],\n        [\n          775.0,\n          184.25925925925924\n        ],\n        [\n          740.0,\n          198.25925925925924\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          860.0,\n          190.0\n        ],\n        [\n          997.0,\n          186.0\n        ],\n        [\n          998.0,\n          305.0\n        ],\n        [\n          924.0,\n          320.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          877.0,\n          353.0\n        ],\n        [\n          869.0,\n          245.0\n        ],\n        [\n          879.0,\n          222.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          924.0,\n          321.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          909.0,\n          388.0\n        ],\n        [\n          936.0,\n          404.0\n        ],\n        [\n          959.0,\n          411.0\n        ],\n        [\n          966.0,\n          431.0\n        ],\n        [\n          1000.0,\n          432.0\n        ],\n        [\n          1000.0,\n          306.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"00000100.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 563,\n  \"imageWidth\": 1000\n}"
  },
  {
    "path": "examples/video_annotation/data_annotated/00000101.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          614.7407407407408,\n          203.2592592592593\n        ],\n        [\n          584.7407407407408,\n          274.2592592592593\n        ],\n        [\n          583.7407407407408,\n          339.2592592592593\n        ],\n        [\n          602.7407407407408,\n          362.2592592592593\n        ],\n        [\n          619.7407407407408,\n          362.2592592592593\n        ],\n        [\n          629.7407407407408,\n          353.2592592592593\n        ],\n        [\n          662.7407407407408,\n          382.2592592592593\n        ],\n        [\n          713.7407407407408,\n          389.2592592592593\n        ],\n        [\n          728.7407407407408,\n          363.2592592592593\n        ],\n        [\n          827.7407407407408,\n          357.2592592592593\n        ],\n        [\n          825.7407407407408,\n          248.2592592592593\n        ],\n        [\n          801.7407407407408,\n          199.2592592592593\n        ],\n        [\n          757.7407407407408,\n          193.2592592592593\n        ],\n        [\n          720.7407407407408,\n          198.2592592592593\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          860.0,\n          190.0\n        ],\n        [\n          997.0,\n          186.0\n        ],\n        [\n          998.0,\n          305.0\n        ],\n        [\n          924.0,\n          320.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          877.0,\n          353.0\n        ],\n        [\n          869.0,\n          245.0\n        ],\n        [\n          879.0,\n          222.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          924.0,\n          321.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          909.0,\n          388.0\n        ],\n        [\n          936.0,\n          404.0\n        ],\n        [\n          959.0,\n          411.0\n        ],\n        [\n          966.0,\n          431.0\n        ],\n        [\n          1000.0,\n          432.0\n        ],\n        [\n          1000.0,\n          306.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"00000101.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 563,\n  \"imageWidth\": 1000\n}"
  },
  {
    "path": "examples/video_annotation/data_annotated/00000102.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          591.5185185185185,\n          202.51851851851853\n        ],\n        [\n          561.5185185185185,\n          273.51851851851853\n        ],\n        [\n          560.5185185185185,\n          338.51851851851853\n        ],\n        [\n          579.5185185185185,\n          361.51851851851853\n        ],\n        [\n          596.5185185185185,\n          361.51851851851853\n        ],\n        [\n          606.5185185185185,\n          352.51851851851853\n        ],\n        [\n          639.5185185185185,\n          381.51851851851853\n        ],\n        [\n          690.5185185185185,\n          388.51851851851853\n        ],\n        [\n          705.5185185185185,\n          362.51851851851853\n        ],\n        [\n          825.5185185185185,\n          356.51851851851853\n        ],\n        [\n          821.5185185185185,\n          241.51851851851853\n        ],\n        [\n          800.5185185185185,\n          197.51851851851853\n        ],\n        [\n          734.5185185185185,\n          192.51851851851853\n        ],\n        [\n          697.5185185185185,\n          197.51851851851853\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          860.0,\n          190.0\n        ],\n        [\n          997.0,\n          186.0\n        ],\n        [\n          998.0,\n          305.0\n        ],\n        [\n          924.0,\n          320.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          877.0,\n          353.0\n        ],\n        [\n          869.0,\n          245.0\n        ],\n        [\n          879.0,\n          222.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          924.0,\n          321.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          909.0,\n          388.0\n        ],\n        [\n          936.0,\n          404.0\n        ],\n        [\n          959.0,\n          411.0\n        ],\n        [\n          966.0,\n          431.0\n        ],\n        [\n          1000.0,\n          432.0\n        ],\n        [\n          1000.0,\n          306.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"00000102.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 563,\n  \"imageWidth\": 1000\n}"
  },
  {
    "path": "examples/video_annotation/data_annotated/00000103.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          573.0,\n          202.55555555555554\n        ],\n        [\n          543.0,\n          273.55555555555554\n        ],\n        [\n          542.0,\n          338.55555555555554\n        ],\n        [\n          561.0,\n          361.55555555555554\n        ],\n        [\n          578.0,\n          361.55555555555554\n        ],\n        [\n          588.0,\n          352.55555555555554\n        ],\n        [\n          621.0,\n          381.55555555555554\n        ],\n        [\n          672.0,\n          388.55555555555554\n        ],\n        [\n          687.0,\n          362.55555555555554\n        ],\n        [\n          829.0,\n          349.55555555555554\n        ],\n        [\n          821.0,\n          231.55555555555554\n        ],\n        [\n          801.0,\n          194.55555555555554\n        ],\n        [\n          716.0,\n          192.55555555555554\n        ],\n        [\n          679.0,\n          197.55555555555554\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          860.0,\n          190.0\n        ],\n        [\n          997.0,\n          186.0\n        ],\n        [\n          998.0,\n          305.0\n        ],\n        [\n          924.0,\n          320.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          877.0,\n          353.0\n        ],\n        [\n          869.0,\n          245.0\n        ],\n        [\n          879.0,\n          222.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          924.0,\n          321.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          909.0,\n          388.0\n        ],\n        [\n          936.0,\n          404.0\n        ],\n        [\n          959.0,\n          411.0\n        ],\n        [\n          966.0,\n          431.0\n        ],\n        [\n          1000.0,\n          432.0\n        ],\n        [\n          1000.0,\n          306.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"00000103.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 563,\n  \"imageWidth\": 1000\n}"
  },
  {
    "path": "examples/video_annotation/data_annotated/00000104.json",
    "content": "{\n  \"version\": \"4.0.0\",\n  \"flags\": {},\n  \"shapes\": [\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          555.2592592592594,\n          200.25925925925924\n        ],\n        [\n          527.2592592592594,\n          276.25925925925924\n        ],\n        [\n          523.2592592592594,\n          341.25925925925924\n        ],\n        [\n          527.2592592592594,\n          360.25925925925924\n        ],\n        [\n          562.2592592592594,\n          364.25925925925924\n        ],\n        [\n          572.2592592592594,\n          355.25925925925924\n        ],\n        [\n          605.2592592592594,\n          384.25925925925924\n        ],\n        [\n          656.2592592592594,\n          391.25925925925924\n        ],\n        [\n          671.2592592592594,\n          365.25925925925924\n        ],\n        [\n          824.2592592592594,\n          353.25925925925924\n        ],\n        [\n          825.2592592592594,\n          237.25925925925924\n        ],\n        [\n          800.2592592592594,\n          201.25925925925924\n        ],\n        [\n          700.2592592592594,\n          195.25925925925924\n        ],\n        [\n          663.2592592592594,\n          200.25925925925924\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"track\",\n      \"points\": [\n        [\n          860.0,\n          190.0\n        ],\n        [\n          997.0,\n          186.0\n        ],\n        [\n          998.0,\n          305.0\n        ],\n        [\n          924.0,\n          320.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          874.0,\n          354.0\n        ],\n        [\n          869.0,\n          245.0\n        ],\n        [\n          879.0,\n          222.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    },\n    {\n      \"label\": \"car\",\n      \"points\": [\n        [\n          924.0,\n          321.0\n        ],\n        [\n          905.0,\n          352.0\n        ],\n        [\n          909.0,\n          388.0\n        ],\n        [\n          936.0,\n          404.0\n        ],\n        [\n          959.0,\n          411.0\n        ],\n        [\n          966.0,\n          431.0\n        ],\n        [\n          1000.0,\n          432.0\n        ],\n        [\n          1000.0,\n          306.0\n        ]\n      ],\n      \"group_id\": null,\n      \"shape_type\": \"polygon\",\n      \"flags\": {}\n    }\n  ],\n  \"imagePath\": \"00000104.jpg\",\n  \"imageData\": null,\n  \"imageHeight\": 563,\n  \"imageWidth\": 1000\n}"
  },
  {
    "path": "examples/video_annotation/data_dataset_voc/class_names.txt",
    "content": "_background_\ncar\ntrack"
  },
  {
    "path": "examples/video_annotation/labels.txt",
    "content": "__ignore__\n_background_\ncar\ntrack\n"
  },
  {
    "path": "labelme/__init__.py",
    "content": "import importlib.metadata\n\n__appname__ = \"Labelme\"\n\n# Semantic Versioning 2.0.0: https://semver.org/\n# 1. MAJOR version when you make incompatible API changes;\n# 2. MINOR version when you add functionality in a backwards-compatible manner;\n# 3. PATCH version when you make backwards-compatible bug fixes.\n# e.g., 1.0.0a0, 1.0.0a1, 1.0.0b0, 1.0.0rc0, 1.0.0, 1.0.0.post0\n__version__ = importlib.metadata.version(\"labelme\")\n\n# XXX: has to be imported before PyQt5 to load dlls in order on Windows\n# https://github.com/wkentaro/labelme/issues/1564\nimport onnxruntime\n\nfrom labelme import utils\nfrom labelme._label_file import LabelFile\n"
  },
  {
    "path": "labelme/__main__.py",
    "content": "import argparse\nimport codecs\nimport contextlib\nimport io\nimport os\nimport os.path as osp\nimport sys\nimport traceback\nimport warnings\nfrom pathlib import Path\nfrom typing import AnyStr\n\nimport yaml\nfrom loguru import logger\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtWidgets\n\nfrom labelme import __appname__\nfrom labelme import __version__\nfrom labelme.app import MainWindow\nfrom labelme.config import get_user_config_file\nfrom labelme.utils import newIcon\n\n\nclass _LoggerIO(io.StringIO):\n    def write(self, s: AnyStr) -> int:\n        assert isinstance(s, str)\n        if stripped_s := s.strip():\n            logger.debug(stripped_s)\n        return len(s)\n\n    def flush(self) -> None:\n        pass\n\n    def writable(self) -> bool:\n        return True\n\n    def readable(self) -> bool:\n        return False\n\n    def seekable(self) -> bool:\n        return False\n\n    @property\n    def closed(self) -> bool:\n        return False\n\n\ndef _setup_loguru(logger_level: str) -> None:\n    try:\n        logger.remove(handler_id=0)\n    except ValueError:\n        pass\n\n    if sys.stderr:\n        logger.add(sys.stderr, level=logger_level)\n\n    cache_dir: str\n    if os.name == \"nt\":\n        cache_dir = os.path.join(os.environ[\"LOCALAPPDATA\"], \"labelme\")\n    else:\n        cache_dir = os.path.expanduser(\"~/.cache/labelme\")\n\n    os.makedirs(cache_dir, exist_ok=True)\n\n    log_file = os.path.join(cache_dir, \"labelme.log\")\n    logger.add(\n        log_file,\n        colorize=True,\n        level=\"DEBUG\",\n        rotation=\"10 MB\",\n        retention=\"30 days\",\n        compression=\"gz\",\n        enqueue=True,\n        backtrace=True,\n        diagnose=True,\n    )\n\n\ndef _handle_exception(exc_type, exc_value, exc_traceback):\n    if issubclass(exc_type, KeyboardInterrupt):\n        sys.__excepthook__(exc_type, exc_value, exc_traceback)\n        sys.exit(0)\n\n    traceback_str: str = \"\".join(\n        traceback.format_exception(exc_type, exc_value, exc_traceback)\n    )\n    logger.critical(traceback_str)\n\n    traceback_html: str = traceback_str.replace(\"\\n\", \"<br/>\").replace(\" \", \"&nbsp;\")\n    QtWidgets.QMessageBox.critical(\n        None,\n        \"Error\",\n        f\"An unexpected error occurred. The application will close.<br/><br/>Please report issues following the <a href='https://labelme.io/docs/troubleshoot'>Troubleshoot</a>.<br/><br/>{traceback_html}\",  # noqa: E501\n    )\n\n    if app := QtWidgets.QApplication.instance():\n        app.quit()\n    sys.exit(1)\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"--version\", \"-V\", action=\"store_true\", help=\"show version\")\n    parser.add_argument(\"--reset-config\", action=\"store_true\", help=\"reset qt config\")\n    parser.add_argument(\n        \"--logger-level\",\n        default=\"debug\",\n        choices=[\"debug\", \"info\", \"warning\", \"fatal\", \"error\"],\n        help=\"logger level\",\n    )\n    parser.add_argument(\"path\", nargs=\"?\", help=\"image file, label file, or directory\")\n    parser.add_argument(\n        \"--output\",\n        help=\"output directory for saving annotation JSON files\",\n    )\n    default_config_file = get_user_config_file()\n    parser.add_argument(\n        \"--config\",\n        dest=\"config\",\n        help=f\"config file or yaml-format string (default: {default_config_file})\",\n        default=default_config_file,\n    )\n    # config for the gui\n    parser.add_argument(\n        \"--nodata\",\n        dest=\"_deprecated_nodata\",\n        action=\"store_true\",\n        help=argparse.SUPPRESS,\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--with-image-data\",\n        dest=\"with_image_data\",\n        action=\"store_true\",\n        help=\"store image data in JSON file\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--no-auto-save\",\n        dest=\"auto_save\",\n        action=\"store_false\",\n        help=\"disable auto save\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--autosave\",\n        dest=\"_deprecated_autosave\",\n        action=\"store_true\",\n        help=argparse.SUPPRESS,\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--no-sort-labels\",\n        \"--nosortlabels\",  # deprecated\n        dest=\"sort_labels\",\n        action=\"store_false\",\n        help=\"stop sorting labels\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--flags\",\n        help=\"comma separated list of flags OR file containing flags\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--label-flags\",\n        \"--labelflags\",  # deprecated\n        dest=\"label_flags\",\n        help=r\"yaml string of label specific flags OR file containing json \"\n        r\"string of label specific flags (ex. {person-\\d+: [male, tall], \"\n        r\"dog-\\d+: [black, brown, white], .*: [occluded]})\",  # NOQA\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--labels\",\n        help=\"comma separated list of labels OR file containing labels\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--validate-label\",\n        \"--validatelabel\",  # deprecated\n        dest=\"validate_label\",\n        choices=[\"exact\"],\n        help=\"label validation types\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--keep-prev\",\n        action=\"store_true\",\n        help=\"keep annotation of previous frame\",\n        default=argparse.SUPPRESS,\n    )\n    parser.add_argument(\n        \"--epsilon\",\n        type=float,\n        help=\"epsilon to find nearest vertex on canvas\",\n        default=argparse.SUPPRESS,\n    )\n    args = parser.parse_args()\n\n    if hasattr(args, \"_deprecated_nodata\"):\n        warnings.warn(\n            \"--nodata is deprecated and will be removed in a future version. \"\n            \"Image data is no longer stored by default. \"\n            \"Use --with-image-data to store it.\",\n            FutureWarning,\n            stacklevel=1,\n        )\n        del args._deprecated_nodata\n\n    if hasattr(args, \"_deprecated_autosave\"):\n        warnings.warn(\n            \"--autosave is deprecated and will be removed in a future version. \"\n            \"Auto save is now enabled by default. Use --no-autosave to disable it.\",\n            FutureWarning,\n            stacklevel=1,\n        )\n        del args._deprecated_autosave\n\n    if args.version:\n        print(f\"{__appname__} {__version__}\")\n        sys.exit(0)\n\n    _setup_loguru(logger_level=args.logger_level.upper())\n    logger.info(\"Starting {} {}\", __appname__, __version__)\n\n    sys.excepthook = _handle_exception\n\n    if hasattr(args, \"flags\"):\n        if os.path.isfile(args.flags):\n            with codecs.open(args.flags, \"r\", encoding=\"utf-8\") as f:\n                args.flags = [line.strip() for line in f if line.strip()]\n        else:\n            args.flags = [line for line in args.flags.split(\",\") if line]\n\n    if hasattr(args, \"labels\"):\n        if os.path.isfile(args.labels):\n            with codecs.open(args.labels, \"r\", encoding=\"utf-8\") as f:\n                args.labels = [line.strip() for line in f if line.strip()]\n        else:\n            args.labels = [line for line in args.labels.split(\",\") if line]\n\n    if hasattr(args, \"label_flags\"):\n        if os.path.isfile(args.label_flags):\n            with codecs.open(args.label_flags, \"r\", encoding=\"utf-8\") as f:\n                args.label_flags = yaml.safe_load(f)\n        else:\n            args.label_flags = yaml.safe_load(args.label_flags)\n\n    config_from_args = args.__dict__\n    config_from_args.pop(\"version\")\n    reset_config = config_from_args.pop(\"reset_config\")\n    filename = config_from_args.pop(\"path\")\n    output = config_from_args.pop(\"output\")\n\n    config_overrides: dict\n    config_file: Path | None\n    config_str: str = config_from_args.pop(\"config\")\n    if isinstance(config_loaded := yaml.safe_load(config_str), dict):\n        config_overrides = config_loaded\n        config_file = None\n    else:\n        config_overrides = {}\n        config_file = Path(config_str)\n        if not config_file.is_file():\n            logger.error(\n                \"Config file does not exist: {!r}\", str(config_file.absolute())\n            )\n            sys.exit(1)\n    del config_str\n    config_overrides.update(config_from_args)\n\n    output_dir = None\n    if output is not None:\n        if output.endswith(\".json\"):\n            parser.error(\n                f\"--output expects a directory path, but '{output}' looks like a file.\"\n                \" Remove the .json extension or provide a directory path.\"\n            )\n        output_dir = output\n\n    translator = QtCore.QTranslator()\n    translator.load(\n        QtCore.QLocale.system().name(),\n        f\"{osp.dirname(osp.abspath(__file__))}/translate\",\n    )\n    app = QtWidgets.QApplication(sys.argv)\n    app.setStyle(\"Fusion\")  # for consistent appearance across platforms\n    # Force light mode to avoid dark mode UI issues (e.g., invisible icons)\n    app.setPalette(QtWidgets.QStyleFactory.create(\"Fusion\").standardPalette())\n    app.setApplicationName(__appname__)\n    app.setWindowIcon(newIcon(\"icon\"))\n    app.installTranslator(translator)\n    win = MainWindow(\n        config_file=config_file,\n        config_overrides=config_overrides,\n        filename=filename,\n        output_dir=output_dir,\n    )\n\n    if reset_config:\n        logger.info(f\"Resetting Qt config: {win.settings.fileName()}\")\n        win.settings.clear()\n        sys.exit(0)\n\n    with contextlib.redirect_stderr(new_target=_LoggerIO()):\n        win.show()\n        win.raise_()\n        sys.exit(app.exec_())\n\n\n# this main block is required to generate executable by pyinstaller\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "labelme/_automation/__init__.py",
    "content": "from ._osam_session import OsamSession\n"
  },
  {
    "path": "labelme/_automation/_osam_session.py",
    "content": "from __future__ import annotations\n\nimport collections\n\nimport numpy as np\nimport osam\nfrom loguru import logger\nfrom numpy.typing import NDArray\n\n\nclass OsamSession:\n    _model_name: str\n    _model: osam.types.Model | None\n    _embedding_cache: collections.deque[tuple[str, osam.types.ImageEmbedding]]\n\n    def __init__(\n        self,\n        model_name: str = \"sam2:latest\",\n        embedding_cache_size: int = 3,\n    ) -> None:\n        logger.debug(\"Initializing OsamSession with model_name={!r}\", model_name)\n        self._model_name = model_name\n        self._model = None\n        self._embedding_cache = collections.deque(maxlen=embedding_cache_size)\n        logger.debug(\"Initialized OsamSession with model_name={!r}\", model_name)\n\n    @property\n    def model_name(self) -> str:\n        return self._model_name\n\n    def run(\n        self,\n        image: NDArray[np.uint8],\n        image_id: str,\n        points: NDArray[np.floating] | None = None,\n        point_labels: NDArray[np.intp] | None = None,\n        texts: list[str] | None = None,\n    ) -> osam.types.GenerateResponse:\n        image_embedding: osam.types.ImageEmbedding | None\n        try:\n            image_embedding = self._get_or_compute_embedding(\n                image=image, image_id=image_id\n            )\n        except NotImplementedError:\n            image_embedding = None\n\n        prompt: osam.types.Prompt\n        if points is not None and point_labels is not None:\n            prompt = osam.types.Prompt(\n                points=points,\n                point_labels=point_labels,\n            )\n        elif texts is not None:\n            prompt = osam.types.Prompt(\n                texts=texts,\n                iou_threshold=1.0,\n                score_threshold=0.01,\n                max_annotations=1000,\n            )\n        else:\n            raise ValueError(\n                \"Either points and point_labels, or texts must be provided.\"\n            )\n\n        model: osam.types.Model = self._get_or_load_model()\n        return model.generate(\n            request=osam.types.GenerateRequest(\n                model=model.name,\n                image=image,\n                image_embedding=image_embedding,\n                prompt=prompt,\n            )\n        )\n\n    def _get_or_compute_embedding(\n        self, image: NDArray[np.uint8], image_id: str\n    ) -> osam.types.ImageEmbedding:\n        for key, embedding in self._embedding_cache:\n            if key == image_id:\n                return embedding\n\n        model: osam.types.Model = self._get_or_load_model()\n        logger.debug(\"Computing embedding for cache_key={!r}\", image_id)\n        embedding: osam.types.ImageEmbedding = model.encode_image(image=image)\n        self._embedding_cache.append((image_id, embedding))\n        logger.debug(\"Cached embedding for cache_key={!r}\", image_id)\n        return embedding\n\n    def _get_or_load_model(self) -> osam.types.Model:\n        if self._model is None:\n            logger.debug(\"Loading model with name={!r}\", self._model_name)\n            self._model = osam.apis.get_model_type_by_name(self._model_name)()\n            logger.debug(\"Loaded model with name={!r}\", self._model_name)\n        return self._model\n"
  },
  {
    "path": "labelme/_automation/bbox_from_text.py",
    "content": "import json\nimport time\nfrom typing import Literal\n\nimport numpy as np\nimport osam\nfrom loguru import logger\nfrom numpy.typing import NDArray\nfrom PyQt5 import QtCore\n\nfrom labelme.shape import Shape\n\nfrom ._osam_session import OsamSession\nfrom .polygon_from_mask import compute_polygon_from_mask\n\n\ndef get_bboxes_from_texts(\n    session: OsamSession, image: np.ndarray, image_id: str, texts: list[str]\n) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray | None]:\n    logger.debug(\n        f\"Requesting with model={session.model_name!r}, \"\n        f\"image={(image.shape, image.dtype)}, texts={texts!r}\"\n    )\n    t_start: float = time.time()\n    response: osam.types.GenerateResponse = session.run(\n        image=image,\n        image_id=image_id,\n        texts=texts,\n    )\n\n    num_annotations: int = len(response.annotations)\n    logger.debug(\n        f\"Response: num_annotations={num_annotations}, \"\n        f\"elapsed_time={time.time() - t_start:.3f} [s]\"\n    )\n\n    boxes: NDArray[np.float32] = np.empty((num_annotations, 4), dtype=np.float32)\n    scores: NDArray[np.float32] = np.empty((num_annotations,), dtype=np.float32)\n    labels: NDArray[np.int32] = np.empty((num_annotations,), dtype=np.int32)\n    for i, annotation in enumerate(response.annotations):\n        if annotation.bounding_box is None:\n            raise ValueError(\"Bounding box is missing in the annotation.\")\n        if annotation.text not in texts:\n            raise ValueError(\n                f\"Unexpected text {annotation.text!r} found in the response.\"\n            )\n        boxes[i] = [\n            annotation.bounding_box.xmin,\n            annotation.bounding_box.ymin,\n            annotation.bounding_box.xmax,\n            annotation.bounding_box.ymax,\n        ]\n        scores[i] = annotation.score\n        labels[i] = texts.index(annotation.text)\n\n    masks: NDArray[np.bool_] | None = None\n    if response.annotations and response.annotations[0].mask is not None:\n        masks = np.array(\n            [annotation.mask for annotation in response.annotations], dtype=np.bool_\n        )\n\n    return boxes, scores, labels, masks\n\n\ndef nms_bboxes(\n    boxes: np.ndarray,\n    scores: np.ndarray,\n    labels: np.ndarray,\n    iou_threshold: float,\n    score_threshold: float,\n    max_num_detections: int,\n) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:\n    if len(boxes) == 0:\n        return boxes, scores, labels, np.empty((0,), dtype=np.int32)\n\n    num_classes: int = max(labels) + 1\n    scores_of_all_classes: NDArray[np.float32] = np.zeros(\n        (len(boxes), num_classes), dtype=np.float32\n    )\n    for i, (score, label) in enumerate(zip(scores, labels)):\n        scores_of_all_classes[i, label] = score\n    logger.debug(\n        \"Running NMS: iou_threshold={}, score_threshold={}, max_num_detections={}\",\n        iou_threshold,\n        score_threshold,\n        max_num_detections,\n    )\n    logger.debug(f\"Input: num_boxes={len(boxes)}\")\n    boxes, scores, labels, indices = osam.apis.non_maximum_suppression(\n        boxes=boxes,\n        scores=scores_of_all_classes,\n        iou_threshold=iou_threshold,\n        score_threshold=score_threshold,\n        max_num_detections=max_num_detections,\n    )\n    logger.debug(f\"Output: num_boxes={len(boxes)}\")\n    return boxes, scores, labels, indices\n\n\ndef get_shapes_from_bboxes(\n    boxes: np.ndarray,\n    scores: np.ndarray,\n    labels: np.ndarray,\n    texts: list[str],\n    masks: NDArray[np.bool_] | None,\n    shape_type: Literal[\"rectangle\", \"polygon\", \"mask\"],\n) -> list[Shape]:\n    shapes: list[Shape] = []\n    for i, (box, score, label) in enumerate(zip(boxes, scores, labels)):\n        text: str = texts[label]\n        xmin, ymin, xmax, ymax = box\n\n        points: list[list[float]]\n        mask: NDArray[np.bool_] | None = None\n        if shape_type == \"rectangle\":\n            points = [[xmin, ymin], [xmax, ymax]]\n        elif shape_type == \"polygon\":\n            if masks is None:\n                points = [\n                    [xmin, ymin],\n                    [xmax, ymin],\n                    [xmax, ymax],\n                    [xmin, ymax],\n                    [xmin, ymin],\n                ]\n            else:\n                points = compute_polygon_from_mask(mask=masks[i]).tolist()\n        elif shape_type == \"mask\":\n            xmin = int(xmin)\n            ymin = int(ymin)\n            xmax = int(xmax)\n            ymax = int(ymax)\n            points = [[xmin, ymin], [xmax, ymax]]\n            if masks is None:\n                mask = np.zeros((ymax - ymin, xmax - xmin), dtype=bool)\n            else:\n                mask = masks[i][ymin : ymax + 1, xmin : xmax + 1]\n        else:\n            raise ValueError(f\"Unsupported shape_type: {shape_type!r}\")\n\n        shape = Shape(\n            label=text,\n            shape_type=shape_type,\n            mask=mask,\n            description=json.dumps(dict(score=score.item(), text=text)),\n        )\n        for point in points:\n            shape.addPoint(QtCore.QPointF(point[0], point[1]))\n        shapes.append(shape)\n    return shapes\n"
  },
  {
    "path": "labelme/_automation/polygon_from_mask.py",
    "content": "import imgviz\nimport numpy as np\nimport skimage\nfrom loguru import logger\nfrom numpy.typing import NDArray\n\n\ndef _get_contour_length(contour: NDArray[np.float32]) -> float:\n    contour_start: NDArray[np.float32] = contour\n    contour_end: NDArray[np.float32] = np.r_[contour[1:], contour[0:1]]\n    return np.linalg.norm(contour_end - contour_start, axis=1).sum()\n\n\ndef compute_polygon_from_mask(mask: NDArray[np.bool_]) -> NDArray[np.float32]:\n    contours: NDArray[np.float32] = skimage.measure.find_contours(\n        np.pad(mask, pad_width=1)\n    )\n    if len(contours) == 0:\n        logger.warning(\"No contour found, so returning empty polygon.\")\n        return np.empty((0, 2), dtype=np.float32)\n\n    contour: NDArray[np.float32] = max(contours, key=_get_contour_length)\n    POLYGON_APPROX_TOLERANCE: float = 0.004\n    polygon: NDArray[np.float32] = skimage.measure.approximate_polygon(\n        coords=contour,\n        tolerance=np.ptp(contour, axis=0).max() * POLYGON_APPROX_TOLERANCE,\n    )\n    polygon = np.clip(polygon, (0, 0), (mask.shape[0] - 1, mask.shape[1] - 1))\n    polygon = polygon[:-1]  # drop last point that is duplicate of first point\n\n    if 0:\n        import PIL.Image\n\n        image_pil = PIL.Image.fromarray(imgviz.gray2rgb(imgviz.bool2ubyte(mask)))\n        imgviz.draw.line_(image_pil, yx=polygon, fill=(0, 255, 0))\n        for point in polygon:\n            imgviz.draw.circle_(image_pil, center=point, diameter=10, fill=(0, 255, 0))\n        imgviz.io.imsave(\"contour.jpg\", np.asarray(image_pil))\n\n    return polygon[:, ::-1]  # yx -> xy\n"
  },
  {
    "path": "labelme/_label_file.py",
    "content": "from __future__ import annotations\n\nimport base64\nimport contextlib\nimport io\nimport json\nimport os.path as osp\nimport time\nfrom pathlib import PureWindowsPath\nfrom typing import TypedDict\n\nimport numpy as np\nimport PIL.Image\nimport tifffile\nfrom loguru import logger\nfrom numpy.typing import NDArray\n\nfrom labelme import __version__\nfrom labelme import utils\n\nPIL.Image.MAX_IMAGE_PIXELS = None\n\n\n@contextlib.contextmanager\ndef _open(name, mode):\n    assert mode in [\"r\", \"w\"]\n    encoding = \"utf-8\"\n    yield open(name, mode, encoding=encoding)\n    return\n\n\nclass ShapeDict(TypedDict):\n    label: str\n    points: list[list[float]]\n    shape_type: str\n    flags: dict[str, bool]\n    description: str\n    group_id: int | None\n    mask: NDArray[np.bool_] | None\n    other_data: dict\n\n\ndef _load_shape_json_obj(shape_json_obj: dict) -> ShapeDict:\n    SHAPE_KEYS: set[str] = {\n        \"label\",\n        \"points\",\n        \"group_id\",\n        \"shape_type\",\n        \"flags\",\n        \"description\",\n        \"mask\",\n    }\n\n    if \"label\" not in shape_json_obj:\n        raise ValueError(f\"label is required: {shape_json_obj}\")\n    if not isinstance(shape_json_obj[\"label\"], str):\n        raise TypeError(f\"label must be str: {shape_json_obj['label']}\")\n    label: str = shape_json_obj[\"label\"]\n\n    if \"points\" not in shape_json_obj:\n        raise ValueError(f\"points is required: {shape_json_obj}\")\n    if not isinstance(shape_json_obj[\"points\"], list):\n        raise TypeError(f\"points must be list: {shape_json_obj['points']}\")\n    if not shape_json_obj[\"points\"]:\n        raise ValueError(f\"points must be non-empty: {shape_json_obj}\")\n    if not all(\n        isinstance(point, list)\n        and len(point) == 2\n        and all(isinstance(xy, int | float) for xy in point)\n        for point in shape_json_obj[\"points\"]\n    ):\n        raise ValueError(f\"points must be list of [x, y]: {shape_json_obj['points']}\")\n    points: list[list[float]] = shape_json_obj[\"points\"]\n\n    if \"shape_type\" not in shape_json_obj:\n        raise ValueError(f\"shape_type is required: {shape_json_obj}\")\n    if not isinstance(shape_json_obj[\"shape_type\"], str):\n        raise TypeError(f\"shape_type must be str: {shape_json_obj['shape_type']}\")\n    shape_type: str = shape_json_obj[\"shape_type\"]\n\n    flags: dict = {}\n    if shape_json_obj.get(\"flags\") is not None:\n        if not isinstance(shape_json_obj[\"flags\"], dict):\n            raise TypeError(f\"flags must be dict: {shape_json_obj['flags']}\")\n        if not all(\n            isinstance(k, str) and isinstance(v, bool)\n            for k, v in shape_json_obj[\"flags\"].items()\n        ):\n            raise TypeError(\n                f\"flags must be dict of str to bool: {shape_json_obj['flags']}\"\n            )\n        flags = shape_json_obj[\"flags\"]\n\n    description: str = \"\"\n    if shape_json_obj.get(\"description\") is not None:\n        if not isinstance(shape_json_obj[\"description\"], str):\n            raise TypeError(f\"description must be str: {shape_json_obj['description']}\")\n        description = shape_json_obj[\"description\"]\n\n    group_id: int | None = None\n    if shape_json_obj.get(\"group_id\") is not None:\n        if not isinstance(shape_json_obj[\"group_id\"], int):\n            raise TypeError(f\"group_id must be int: {shape_json_obj['group_id']}\")\n        group_id = shape_json_obj[\"group_id\"]\n\n    mask: NDArray[np.bool_] | None = None\n    if shape_json_obj.get(\"mask\") is not None:\n        if not isinstance(shape_json_obj[\"mask\"], str):\n            raise TypeError(\n                f\"mask must be base64-encoded PNG: {shape_json_obj['mask']}\"\n            )\n        mask = utils.img_b64_to_arr(shape_json_obj[\"mask\"]).astype(bool)\n\n    other_data = {k: v for k, v in shape_json_obj.items() if k not in SHAPE_KEYS}\n\n    loaded: ShapeDict = ShapeDict(\n        label=label,\n        points=points,\n        shape_type=shape_type,\n        flags=flags,\n        description=description,\n        group_id=group_id,\n        mask=mask,\n        other_data=other_data,\n    )\n    if set(loaded.keys()) != SHAPE_KEYS | {\"other_data\"}:\n        raise RuntimeError(\n            f\"unexpected keys: {set(loaded.keys())} != {SHAPE_KEYS | {'other_data'}}\"\n        )\n    return loaded\n\n\nclass LabelFileError(Exception):\n    pass\n\n\nclass LabelFile:\n    shapes: list[ShapeDict]\n    suffix = \".json\"\n\n    def __init__(self, filename: str | None = None):\n        self.shapes: list[ShapeDict] = []\n        self.imagePath: str | None = None\n        self.imageData: bytes | None = None\n        if filename is not None:\n            self.load(filename)\n        self.filename: str | None = filename\n\n    @staticmethod\n    def load_image_file(filename):\n        t0 = time.time()\n        image_pil = _imread(filename=filename)\n\n        oriented: PIL.Image.Image = utils.apply_exif_orientation(image_pil)\n        ext = osp.splitext(filename)[1].lower()\n        if oriented is image_pil and ext in (\".jpg\", \".jpeg\", \".png\"):\n            # no encoding needed\n            with open(filename, \"rb\") as f:\n                imageData = f.read()\n        else:\n            with io.BytesIO() as f:\n                format = \"PNG\" if \"A\" in oriented.mode else \"JPEG\"\n                oriented.save(f, format=format, quality=95)\n                f.seek(0)\n                imageData = f.read()\n\n        logger.debug(\n            \"Loaded image file: {!r} in {:.0f}ms\", filename, (time.time() - t0) * 1000\n        )\n        return imageData\n\n    def load(self, filename):\n        keys = [\n            \"version\",\n            \"imageData\",\n            \"imagePath\",\n            \"shapes\",  # polygonal annotations\n            \"flags\",  # image level flags\n            \"imageHeight\",\n            \"imageWidth\",\n        ]\n        try:\n            with _open(filename, \"r\") as f:\n                data = json.load(f)\n\n            # Normalize Windows-style backslash paths to POSIX forward slashes\n            imagePath = PureWindowsPath(data[\"imagePath\"]).as_posix()\n\n            if data[\"imageData\"] is not None:\n                imageData = base64.b64decode(data[\"imageData\"])\n            else:\n                # relative path from label file to relative path from cwd\n                imageData = self.load_image_file(\n                    osp.join(osp.dirname(filename), imagePath)\n                )\n            flags = data.get(\"flags\") or {}\n            self._check_image_height_and_width(\n                imageData,\n                data.get(\"imageHeight\"),\n                data.get(\"imageWidth\"),\n            )\n            shapes: list[ShapeDict] = [\n                _load_shape_json_obj(shape_json_obj=s) for s in data[\"shapes\"]\n            ]\n        except Exception as e:\n            raise LabelFileError(e)\n\n        otherData = {}\n        for key, value in data.items():\n            if key not in keys:\n                otherData[key] = value\n\n        # Only replace data after everything is loaded.\n        self.flags = flags\n        self.shapes = shapes\n        self.imagePath = imagePath\n        self.imageData = imageData\n        self.filename = filename\n        self.otherData = otherData\n\n    @staticmethod\n    def _check_image_height_and_width(imageData, imageHeight, imageWidth):\n        img_pil = utils.img_data_to_pil(imageData)\n        actual_w, actual_h = img_pil.size\n        if imageHeight is not None and actual_h != imageHeight:\n            logger.error(\n                \"imageHeight does not match with imageData or imagePath, \"\n                \"so getting imageHeight from actual image.\"\n            )\n            imageHeight = actual_h\n        if imageWidth is not None and actual_w != imageWidth:\n            logger.error(\n                \"imageWidth does not match with imageData or imagePath, \"\n                \"so getting imageWidth from actual image.\"\n            )\n            imageWidth = actual_w\n        return imageHeight, imageWidth\n\n    def save(\n        self,\n        filename,\n        shapes,\n        imagePath,\n        imageHeight,\n        imageWidth,\n        imageData=None,\n        otherData=None,\n        flags=None,\n    ):\n        if imageData is not None:\n            imageHeight, imageWidth = self._check_image_height_and_width(\n                imageData, imageHeight, imageWidth\n            )\n            imageData = base64.b64encode(imageData).decode(\"utf-8\")\n        if otherData is None:\n            otherData = {}\n        if flags is None:\n            flags = {}\n        data = dict(\n            version=__version__,\n            flags=flags,\n            shapes=shapes,\n            imagePath=imagePath,\n            imageData=imageData,\n            imageHeight=imageHeight,\n            imageWidth=imageWidth,\n        )\n        for key, value in otherData.items():\n            assert key not in data\n            data[key] = value\n        try:\n            with _open(filename, \"w\") as f:\n                json.dump(data, f, ensure_ascii=False, indent=2)\n            self.filename = filename\n        except Exception as e:\n            raise LabelFileError(e)\n\n    @staticmethod\n    def is_label_file(filename):\n        return osp.splitext(filename)[1].lower() == LabelFile.suffix\n\n\n_DISPLAYABLE_MODES = {\"1\", \"L\", \"P\", \"RGB\", \"RGBA\", \"LA\", \"PA\"}\n\n\ndef _imread(filename: str) -> PIL.Image.Image:\n    ext: str = osp.splitext(filename)[1].lower()\n    try:\n        image_pil = PIL.Image.open(filename)\n        if image_pil.mode not in _DISPLAYABLE_MODES:\n            raise PIL.UnidentifiedImageError\n        return image_pil\n    except PIL.UnidentifiedImageError:\n        if ext in (\".tif\", \".tiff\"):\n            return _imread_tiff(filename)\n        raise\n\n\ndef _imread_tiff(filename: str) -> PIL.Image.Image:\n    img_arr: NDArray = tifffile.imread(filename)\n\n    if img_arr.ndim == 2:\n        img_arr_normalized = _normalize_to_uint8(img_arr)\n    elif img_arr.ndim == 3:\n        if img_arr.shape[2] >= 3:\n            img_arr_normalized = np.stack(\n                [_normalize_to_uint8(img_arr[:, :, i]) for i in range(3)],\n                axis=2,\n            )\n        else:\n            img_arr_normalized = _normalize_to_uint8(img_arr[:, :, 0])\n    else:\n        raise OSError(f\"Unsupported image shape: {img_arr.shape}\")\n\n    return PIL.Image.fromarray(img_arr_normalized)\n\n\ndef _normalize_to_uint8(arr: NDArray) -> NDArray[np.uint8]:\n    arr = arr.astype(np.float64)\n    min_val = np.nanmin(arr)\n    max_val = np.nanmax(arr)\n    if np.isnan(min_val) or np.isnan(max_val) or max_val - min_val == 0:\n        return np.zeros(arr.shape, dtype=np.uint8)\n    normalized = (arr - min_val) / (max_val - min_val) * 255\n    return np.clip(normalized, 0, 255).astype(np.uint8)\n"
  },
  {
    "path": "labelme/app.py",
    "content": "from __future__ import annotations\n\nimport enum\nimport functools\nimport html\nimport math\nimport os\nimport os.path as osp\nimport platform\nimport re\nimport subprocess\nimport time\nimport webbrowser\nfrom collections.abc import Callable\nfrom pathlib import Path\nfrom typing import Literal\nfrom typing import NamedTuple\n\nimport imgviz\nimport natsort\nimport numpy as np\nimport osam\nfrom loguru import logger\nfrom numpy.typing import NDArray\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\nfrom PyQt5.QtWidgets import QMessageBox\n\nfrom labelme import __appname__\nfrom labelme import __version__\nfrom labelme._automation import bbox_from_text\nfrom labelme._automation._osam_session import OsamSession\nfrom labelme._label_file import LabelFile\nfrom labelme._label_file import LabelFileError\nfrom labelme._label_file import ShapeDict\nfrom labelme.config import load_config\nfrom labelme.shape import Shape\nfrom labelme.widgets import AiAssistedAnnotationWidget\nfrom labelme.widgets import AiTextToAnnotationWidget\nfrom labelme.widgets import BrightnessContrastDialog\nfrom labelme.widgets import Canvas\nfrom labelme.widgets import FileDialogPreview\nfrom labelme.widgets import LabelDialog\nfrom labelme.widgets import LabelListWidget\nfrom labelme.widgets import LabelListWidgetItem\nfrom labelme.widgets import StatusStats\nfrom labelme.widgets import ToolBar\nfrom labelme.widgets import UniqueLabelQListWidget\nfrom labelme.widgets import ZoomWidget\nfrom labelme.widgets import download_ai_model\n\nfrom . import utils\n\n# handle high-dpi scaling issue\n# https://leomoon.com/journal/python/high-dpi-scaling-in-pyqt5\nif hasattr(QtCore.Qt, \"AA_EnableHighDpiScaling\"):\n    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)\nif hasattr(QtCore.Qt, \"AA_UseHighDpiPixmaps\"):\n    QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)\n\n\nLABEL_COLORMAP: NDArray[np.uint8] = imgviz.label_colormap()\n\n\nclass _ZoomMode(enum.Enum):\n    FIT_WINDOW = enum.auto()\n    FIT_WIDTH = enum.auto()\n    MANUAL_ZOOM = enum.auto()\n\n\n_AI_TEXT_TO_ANNOTATION_CREATE_MODE_TO_SHAPE_TYPE: dict[\n    str, Literal[\"mask\", \"polygon\", \"rectangle\"]\n] = {\n    \"ai_mask\": \"mask\",\n    \"ai_polygon\": \"polygon\",\n    \"polygon\": \"polygon\",\n    \"rectangle\": \"rectangle\",\n}\n\n\nclass _StatusBarWidgets(NamedTuple):\n    message: QtWidgets.QLabel\n    stats: StatusStats\n\n\nclass _CanvasWidgets(NamedTuple):\n    canvas: Canvas\n    zoom_widget: ZoomWidget\n    scroll_bars: dict[Qt.Orientation, QtWidgets.QScrollBar]\n\n\nclass _DockWidgets(NamedTuple):\n    flag_dock: QtWidgets.QDockWidget\n    flag_list: QtWidgets.QListWidget\n    shape_dock: QtWidgets.QDockWidget\n    label_list: LabelListWidget\n    label_dock: QtWidgets.QDockWidget\n    unique_label_list: UniqueLabelQListWidget\n    file_dock: QtWidgets.QDockWidget\n    file_search: QtWidgets.QLineEdit\n    file_list: QtWidgets.QListWidget\n\n\nclass _Actions(NamedTuple):\n    about: QtWidgets.QAction\n    save: QtWidgets.QAction\n    save_as: QtWidgets.QAction\n    save_auto: QtWidgets.QAction\n    save_with_image_data: QtWidgets.QAction\n    change_output_dir: QtWidgets.QAction\n    open: QtWidgets.QAction\n    close: QtWidgets.QAction\n    delete_file: QtWidgets.QAction\n    toggle_keep_prev_mode: QtWidgets.QAction\n    toggle_keep_prev_brightness_contrast: QtWidgets.QAction\n    delete: QtWidgets.QAction\n    edit: QtWidgets.QAction\n    duplicate: QtWidgets.QAction\n    copy: QtWidgets.QAction\n    paste: QtWidgets.QAction\n    undo_last_point: QtWidgets.QAction\n    undo: QtWidgets.QAction\n    remove_point: QtWidgets.QAction\n    create_mode: QtWidgets.QAction\n    edit_mode: QtWidgets.QAction\n    create_rectangle_mode: QtWidgets.QAction\n    create_circle_mode: QtWidgets.QAction\n    create_line_mode: QtWidgets.QAction\n    create_point_mode: QtWidgets.QAction\n    create_line_strip_mode: QtWidgets.QAction\n    create_ai_polygon_mode: QtWidgets.QAction\n    create_ai_mask_mode: QtWidgets.QAction\n    open_next_img: QtWidgets.QAction\n    open_prev_img: QtWidgets.QAction\n    keep_prev_scale: QtWidgets.QAction\n    fit_window: QtWidgets.QAction\n    fit_width: QtWidgets.QAction\n    brightness_contrast: QtWidgets.QAction\n    zoom_in: QtWidgets.QAction\n    zoom_out: QtWidgets.QAction\n    zoom_org: QtWidgets.QAction\n    reset_layout: QtWidgets.QAction\n    fill_drawing: QtWidgets.QAction\n    hide_all: QtWidgets.QAction\n    show_all: QtWidgets.QAction\n    toggle_all: QtWidgets.QAction\n    open_dir: QtWidgets.QAction\n    zoom_widget_action: QtWidgets.QWidgetAction\n    draw: list[tuple[str, QtWidgets.QAction]]\n    zoom: tuple[ZoomWidget | QtWidgets.QAction, ...]\n    on_load_active: tuple[QtWidgets.QAction, ...]\n    on_shapes_present: tuple[QtWidgets.QAction, ...]\n    context_menu: tuple[QtWidgets.QAction, ...]\n    edit_menu: tuple[QtWidgets.QAction | None, ...]\n\n\nclass _Menus(NamedTuple):\n    file: QtWidgets.QMenu\n    edit: QtWidgets.QMenu\n    view: QtWidgets.QMenu\n    help: QtWidgets.QMenu\n    recent_files: QtWidgets.QMenu\n    label_list: QtWidgets.QMenu\n\n\nclass MainWindow(QtWidgets.QMainWindow):\n    _config_file: Path | None\n    _config: dict\n\n    _text_osam_session: OsamSession | None = None\n    _is_changed: bool = False\n    _copied_shapes: list[Shape]\n    _zoom_mode: _ZoomMode\n    _prev_opened_dir: str | None\n    _canvas_widgets: _CanvasWidgets\n    _status_bar: _StatusBarWidgets\n    _docks: _DockWidgets\n    _actions: _Actions\n    _menus: _Menus\n    _scalers: dict[_ZoomMode, Callable[[], float]]\n    _label_dialog: LabelDialog\n    _ai_annotation: AiAssistedAnnotationWidget\n    _ai_text: AiTextToAnnotationWidget\n\n    _output_dir: str | None\n    _filename: str | None\n    _image: QtGui.QImage\n    _label_file: LabelFile | None\n    _image_path: str | None\n    _recent_files: list[str]\n    _max_recent: int\n    _other_data: dict | None\n    _zoom_values: dict[str, tuple[_ZoomMode, int]]\n    _brightness_contrast_values: dict[str, tuple[int | None, int | None]]\n    _scroll_values: dict[Qt.Orientation, dict[str, float]]\n    _default_state: QtCore.QByteArray\n\n    def __init__(\n        self,\n        config_file: Path | None = None,\n        config_overrides: dict | None = None,\n        filename: str | None = None,\n        output_dir: str | None = None,\n    ) -> None:\n        super().__init__()\n        self.setWindowTitle(__appname__)\n\n        self._config_file, self._config = self._load_config(\n            config_file=config_file, config_overrides=config_overrides\n        )\n\n        # set default shape colors\n        Shape.line_color = QtGui.QColor(*self._config[\"shape\"][\"line_color\"])\n        Shape.fill_color = QtGui.QColor(*self._config[\"shape\"][\"fill_color\"])\n        Shape.select_line_color = QtGui.QColor(\n            *self._config[\"shape\"][\"select_line_color\"]\n        )\n        Shape.select_fill_color = QtGui.QColor(\n            *self._config[\"shape\"][\"select_fill_color\"]\n        )\n        Shape.vertex_fill_color = QtGui.QColor(\n            *self._config[\"shape\"][\"vertex_fill_color\"]\n        )\n        Shape.hvertex_fill_color = QtGui.QColor(\n            *self._config[\"shape\"][\"hvertex_fill_color\"]\n        )\n\n        # Set point size from config file\n        Shape.point_size = self._config[\"shape\"][\"point_size\"]\n\n        self._copied_shapes = []\n\n        self._label_dialog = LabelDialog(\n            parent=self,\n            labels=self._config[\"labels\"],\n            sort_labels=self._config[\"sort_labels\"],\n            show_text_field=self._config[\"show_label_text_field\"],\n            completion=self._config[\"label_completion\"],\n            fit_to_content=self._config[\"fit_to_content\"],\n            flags=self._config[\"label_flags\"],\n        )\n\n        self._prev_opened_dir = None\n        self._docks = self._setup_dock_widgets()\n\n        self.setAcceptDrops(True)\n        self._canvas_widgets = self._setup_canvas()\n\n        self._actions = self._setup_actions()\n        self._scalers = {\n            _ZoomMode.FIT_WINDOW: self.scaleFitWindow,\n            _ZoomMode.FIT_WIDTH: self.scaleFitWidth,\n            _ZoomMode.MANUAL_ZOOM: lambda: 1,\n        }\n        self._menus = self._setup_menus()\n\n        self._ai_annotation = AiAssistedAnnotationWidget(\n            default_model=self._config[\"ai\"][\"default\"],\n            on_model_changed=self._canvas_widgets.canvas.set_ai_model_name,\n            parent=self,\n        )\n        self._ai_annotation.setEnabled(False)\n\n        self._ai_text = AiTextToAnnotationWidget(\n            on_submit=self._submit_ai_prompt, parent=self\n        )\n        self._ai_text.setEnabled(False)\n\n        self._setup_toolbars()\n\n        self._status_bar = self._setup_status_bar()\n\n        self._setup_app_state(output_dir=output_dir, filename=filename)\n\n        self.updateFileMenu()\n\n        self._canvas_widgets.zoom_widget.valueChanged.connect(self._paint_canvas)\n\n        self.populateModeActions()\n\n    def _setup_actions(self) -> _Actions:\n        action = functools.partial(utils.newAction, self)\n        shortcuts = self._config[\"shortcuts\"]\n\n        about = action(\n            text=f\"&About {__appname__}\",\n            slot=functools.partial(\n                QMessageBox.about,\n                self,\n                f\"About {__appname__}\",\n                f\"\"\"\n<h3>{__appname__}</h3>\n<p>Image Polygonal Annotation with Python</p>\n<p>Version: {__version__}</p>\n<p>Author: Kentaro Wada</p>\n<p>\n    <a href=\"https://labelme.io\">Homepage</a> |\n    <a href=\"https://labelme.io/docs\">Documentation</a> |\n    <a href=\"https://labelme.io/docs/troubleshoot\">Troubleshooting</a>\n</p>\n<p>\n    <a href=\"https://github.com/wkentaro/labelme\">GitHub</a> |\n    <a href=\"https://x.com/labelmeai\">Twitter/X</a>\n</p>\n\"\"\",\n            ),\n        )\n        save = action(\n            text=self.tr(\"&Save\\n\"),\n            slot=self.saveFile,\n            shortcut=shortcuts[\"save\"],\n            icon=\"floppy-disk.svg\",\n            tip=self.tr(\"Save labels to file\"),\n            enabled=False,\n        )\n        save_as = action(\n            text=self.tr(\"&Save As\"),\n            slot=self.saveFileAs,\n            shortcut=shortcuts[\"save_as\"],\n            icon=\"floppy-disk.svg\",\n            tip=self.tr(\"Save labels to a different file\"),\n            enabled=False,\n        )\n        save_auto = action(\n            text=self.tr(\"Save &Automatically\"),\n            tip=self.tr(\"Save automatically\"),\n            checkable=True,\n            enabled=True,\n        )\n        save_auto.setChecked(self._config[\"auto_save\"])\n        save_with_image_data = action(\n            text=self.tr(\"Save With Image Data\"),\n            slot=self.enableSaveImageWithData,\n            tip=self.tr(\"Save image data in label file\"),\n            checkable=True,\n            checked=self._config[\"with_image_data\"],\n        )\n        change_output_dir = action(\n            text=self.tr(\"&Change Output Dir\"),\n            slot=self.changeOutputDirDialog,\n            shortcut=shortcuts[\"save_to\"],\n            icon=\"folders.svg\",\n            tip=self.tr(\"Change where annotations are loaded/saved\"),\n        )\n        open_ = action(\n            text=self.tr(\"&Open\\n\"),\n            slot=self._open_file_with_dialog,\n            shortcut=shortcuts[\"open\"],\n            icon=\"folder-open.svg\",\n            tip=self.tr(\"Open image or label file\"),\n        )\n        open_dir = action(\n            text=self.tr(\"Open Dir\"),\n            slot=self._open_dir_with_dialog,\n            shortcut=shortcuts[\"open_dir\"],\n            icon=\"folder-open.svg\",\n            tip=self.tr(\"Open Dir\"),\n        )\n        close = action(\n            text=self.tr(\"&Close\"),\n            slot=self.closeFile,\n            shortcut=shortcuts[\"close\"],\n            icon=\"x-circle.svg\",\n            tip=self.tr(\"Close current file\"),\n        )\n        delete_file = action(\n            text=self.tr(\"&Delete File\"),\n            slot=self.deleteFile,\n            shortcut=shortcuts[\"delete_file\"],\n            icon=\"file-x.svg\",\n            tip=self.tr(\"Delete current label file\"),\n            enabled=False,\n        )\n        toggle_keep_prev_mode = action(\n            text=self.tr(\"Keep Previous Annotation\"),\n            slot=self.toggleKeepPrevMode,\n            shortcut=shortcuts[\"toggle_keep_prev_mode\"],\n            icon=None,\n            tip=self.tr('Toggle \"keep previous annotation\" mode'),\n            checkable=True,\n        )\n        toggle_keep_prev_mode.setChecked(self._config[\"keep_prev\"])\n        toggle_keep_prev_brightness_contrast = action(\n            text=self.tr(\"Keep Previous Brightness/Contrast\"),\n            slot=lambda: self._config.__setitem__(\n                \"keep_prev_brightness_contrast\",\n                not self._config[\"keep_prev_brightness_contrast\"],\n            ),\n            checkable=True,\n            checked=self._config[\"keep_prev_brightness_contrast\"],\n        )\n        delete = action(\n            self.tr(\"Delete Shapes\"),\n            self.deleteSelectedShape,\n            shortcuts[\"delete_shape\"],\n            icon=\"trash.svg\",\n            tip=self.tr(\"Delete the selected shapes\"),\n            enabled=False,\n        )\n        edit = action(\n            self.tr(\"&Edit Label\"),\n            self._edit_label,\n            shortcuts[\"edit_label\"],\n            icon=\"note-pencil.svg\",\n            tip=self.tr(\"Modify the label of the selected shape\"),\n            enabled=False,\n        )\n        duplicate = action(\n            self.tr(\"Duplicate Shapes\"),\n            self.duplicateSelectedShape,\n            shortcuts[\"duplicate_shape\"],\n            icon=\"copy.svg\",\n            tip=self.tr(\"Create a duplicate of the selected shapes\"),\n            enabled=False,\n        )\n        copy = action(\n            self.tr(\"Copy Shapes\"),\n            self.copySelectedShape,\n            shortcuts[\"copy_shape\"],\n            \"copy_clipboard\",\n            self.tr(\"Copy selected shapes to clipboard\"),\n            enabled=False,\n        )\n        paste = action(\n            self.tr(\"Paste Shapes\"),\n            self.pasteSelectedShape,\n            shortcuts[\"paste_shape\"],\n            \"paste\",\n            self.tr(\"Paste copied shapes\"),\n            enabled=False,\n        )\n        undo_last_point = action(\n            self.tr(\"Undo last point\"),\n            self._canvas_widgets.canvas.undoLastPoint,\n            shortcuts[\"undo_last_point\"],\n            icon=\"arrow-u-up-left.svg\",\n            tip=self.tr(\"Undo last drawn point\"),\n            enabled=False,\n        )\n        undo = action(\n            self.tr(\"Undo\\n\"),\n            self.undoShapeEdit,\n            shortcuts[\"undo\"],\n            icon=\"arrow-u-up-left.svg\",\n            tip=self.tr(\"Undo last add and edit of shape\"),\n            enabled=False,\n        )\n        remove_point = action(\n            text=self.tr(\"Remove Selected Point\"),\n            slot=self.removeSelectedPoint,\n            shortcut=shortcuts[\"remove_selected_point\"],\n            icon=\"trash.svg\",\n            tip=self.tr(\"Remove selected point from polygon\"),\n            enabled=False,\n        )\n        create_mode = action(\n            text=self.tr(\"Create Polygons\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"polygon\"),\n            shortcut=shortcuts[\"create_polygon\"],\n            icon=\"polygon.svg\",\n            tip=self.tr(\"Start drawing polygons\"),\n            enabled=False,\n        )\n        edit_mode = action(\n            self.tr(\"Edit Shapes\"),\n            lambda: self._switch_canvas_mode(edit=True),\n            shortcuts[\"edit_shape\"],\n            icon=\"note-pencil.svg\",\n            tip=self.tr(\"Move and edit the selected shapes\"),\n            enabled=False,\n        )\n        create_rectangle_mode = action(\n            text=self.tr(\"Create Rectangle\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"rectangle\"),\n            shortcut=shortcuts[\"create_rectangle\"],\n            icon=\"rectangle.svg\",\n            tip=self.tr(\"Start drawing rectangles\"),\n            enabled=False,\n        )\n        create_circle_mode = action(\n            text=self.tr(\"Create Circle\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"circle\"),\n            shortcut=shortcuts[\"create_circle\"],\n            icon=\"circle.svg\",\n            tip=self.tr(\"Start drawing circles\"),\n            enabled=False,\n        )\n        create_line_mode = action(\n            text=self.tr(\"Create Line\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"line\"),\n            shortcut=shortcuts[\"create_line\"],\n            icon=\"line-segment.svg\",\n            tip=self.tr(\"Start drawing lines\"),\n            enabled=False,\n        )\n        create_point_mode = action(\n            text=self.tr(\"Create Point\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"point\"),\n            shortcut=shortcuts[\"create_point\"],\n            icon=\"circles-four.svg\",\n            tip=self.tr(\"Start drawing points\"),\n            enabled=False,\n        )\n        create_line_strip_mode = action(\n            text=self.tr(\"Create LineStrip\"),\n            slot=lambda: self._switch_canvas_mode(edit=False, createMode=\"linestrip\"),\n            shortcut=shortcuts[\"create_linestrip\"],\n            icon=\"line-segments.svg\",\n            tip=self.tr(\"Start drawing linestrip. Ctrl+LeftClick ends creation.\"),\n            enabled=False,\n        )\n        create_ai_polygon_mode = action(\n            self.tr(\"Create AI-Polygon\"),\n            lambda: self._switch_canvas_mode(edit=False, createMode=\"ai_polygon\"),\n            None,\n            \"ai-polygon.svg\",\n            self.tr(\"Start drawing ai_polygon. Ctrl+LeftClick ends creation.\"),\n            enabled=False,\n        )\n        create_ai_mask_mode = action(\n            self.tr(\"Create AI-Mask\"),\n            lambda: self._switch_canvas_mode(edit=False, createMode=\"ai_mask\"),\n            None,\n            \"ai-mask.svg\",\n            self.tr(\"Start drawing ai_mask. Ctrl+LeftClick ends creation.\"),\n            enabled=False,\n        )\n        open_next_img = action(\n            text=self.tr(\"&Next Image\"),\n            slot=self._open_next_image,\n            shortcut=shortcuts[\"open_next\"],\n            icon=\"arrow-fat-right.svg\",\n            tip=self.tr(\"Open next (hold Ctl+Shift to copy labels)\"),\n            enabled=False,\n        )\n        open_prev_img = action(\n            text=self.tr(\"&Prev Image\"),\n            slot=self._open_prev_image,\n            shortcut=shortcuts[\"open_prev\"],\n            icon=\"arrow-fat-left.svg\",\n            tip=self.tr(\"Open prev (hold Ctl+Shift to copy labels)\"),\n            enabled=False,\n        )\n        keep_prev_scale = action(\n            self.tr(\"&Keep Previous Scale\"),\n            self.enableKeepPrevScale,\n            tip=self.tr(\"Keep previous zoom scale\"),\n            checkable=True,\n            checked=self._config[\"keep_prev_scale\"],\n            enabled=True,\n        )\n        fit_window = action(\n            self.tr(\"&Fit Window\"),\n            self.setFitWindow,\n            shortcuts[\"fit_window\"],\n            icon=\"frame-corners.svg\",\n            tip=self.tr(\"Zoom follows window size\"),\n            checkable=True,\n            enabled=False,\n        )\n        fit_width = action(\n            self.tr(\"Fit &Width\"),\n            self.setFitWidth,\n            shortcuts[\"fit_width\"],\n            icon=\"frame-arrows-horizontal.svg\",\n            tip=self.tr(\"Zoom follows window width\"),\n            checkable=True,\n            enabled=False,\n        )\n        brightness_contrast = action(\n            self.tr(\"&Brightness Contrast\"),\n            self.brightnessContrast,\n            None,\n            \"brightness-contrast.svg\",\n            self.tr(\"Adjust brightness and contrast\"),\n            enabled=False,\n        )\n        zoom_in = action(\n            self.tr(\"Zoom &In\"),\n            lambda _: self._add_zoom(increment=1.1),\n            shortcuts[\"zoom_in\"],\n            icon=\"magnifying-glass-minus.svg\",\n            tip=self.tr(\"Increase zoom level\"),\n            enabled=False,\n        )\n        zoom_out = action(\n            self.tr(\"&Zoom Out\"),\n            lambda _: self._add_zoom(increment=0.9),\n            shortcuts[\"zoom_out\"],\n            icon=\"magnifying-glass-plus.svg\",\n            tip=self.tr(\"Decrease zoom level\"),\n            enabled=False,\n        )\n        zoom_org = action(\n            self.tr(\"&Original size\"),\n            self._set_zoom_to_original,\n            shortcuts[\"zoom_to_original\"],\n            icon=\"image-square.svg\",\n            tip=self.tr(\"Zoom to original size\"),\n            enabled=False,\n        )\n        reset_layout = action(\n            text=self.tr(\"Reset Layout\"),\n            slot=self._reset_layout,\n            icon=\"layout-duotone.svg\",\n        )\n        fill_drawing = action(\n            self.tr(\"Fill Drawing Polygon\"),\n            self._canvas_widgets.canvas.setFillDrawing,\n            None,\n            icon=\"paint-bucket.svg\",\n            tip=self.tr(\"Fill polygon while drawing\"),\n            checkable=True,\n            enabled=True,\n        )\n        if self._config[\"canvas\"][\"fill_drawing\"]:\n            fill_drawing.trigger()\n        hide_all = action(\n            self.tr(\"&Hide\\nShapes\"),\n            functools.partial(self.toggleShapes, False),\n            shortcuts[\"hide_all_shapes\"],\n            icon=\"eye.svg\",\n            tip=self.tr(\"Hide all shapes\"),\n            enabled=False,\n        )\n        show_all = action(\n            self.tr(\"&Show\\nShapes\"),\n            functools.partial(self.toggleShapes, True),\n            shortcuts[\"show_all_shapes\"],\n            icon=\"eye.svg\",\n            tip=self.tr(\"Show all shapes\"),\n            enabled=False,\n        )\n        toggle_all = action(\n            self.tr(\"&Toggle\\nShapes\"),\n            functools.partial(self.toggleShapes, None),\n            shortcuts[\"toggle_all_shapes\"],\n            icon=\"eye.svg\",\n            tip=self.tr(\"Toggle all shapes\"),\n            enabled=False,\n        )\n\n        zoom_widget_action = QtWidgets.QWidgetAction(self)\n        zoom_box_layout = QtWidgets.QVBoxLayout()\n        zoom_label = QtWidgets.QLabel(self.tr(\"Zoom\"))\n        zoom_label.setAlignment(Qt.AlignCenter)\n        zoom_box_layout.addWidget(zoom_label)\n        zoom_box_layout.addWidget(self._canvas_widgets.zoom_widget)\n        zoom_widget_action.setDefaultWidget(QtWidgets.QWidget())\n        zoom_widget_action.defaultWidget().setLayout(zoom_box_layout)\n        self._canvas_widgets.zoom_widget.setWhatsThis(\n            str(\n                self.tr(\n                    \"Zoom in or out of the image. Also accessible with \"\n                    \"{} and {} from the canvas.\"\n                )\n            ).format(\n                utils.fmtShortcut(f\"{shortcuts['zoom_in']},{shortcuts['zoom_out']}\"),\n                utils.fmtShortcut(self.tr(\"Ctrl+Wheel\")),\n            )\n        )\n        self._canvas_widgets.zoom_widget.setEnabled(False)\n\n        self._zoom_mode = _ZoomMode.FIT_WINDOW\n        fit_window.setChecked(Qt.Checked)\n\n        self._canvas_widgets.canvas.vertexSelected.connect(remove_point.setEnabled)\n\n        draw = [\n            (\"polygon\", create_mode),\n            (\"rectangle\", create_rectangle_mode),\n            (\"circle\", create_circle_mode),\n            (\"point\", create_point_mode),\n            (\"line\", create_line_mode),\n            (\"linestrip\", create_line_strip_mode),\n            (\"ai_polygon\", create_ai_polygon_mode),\n            (\"ai_mask\", create_ai_mask_mode),\n        ]\n        zoom = (\n            self._canvas_widgets.zoom_widget,\n            zoom_in,\n            zoom_out,\n            zoom_org,\n            fit_window,\n            fit_width,\n        )\n        on_load_active = (\n            close,\n            create_mode,\n            create_rectangle_mode,\n            create_circle_mode,\n            create_line_mode,\n            create_point_mode,\n            create_line_strip_mode,\n            create_ai_polygon_mode,\n            create_ai_mask_mode,\n            brightness_contrast,\n        )\n        on_shapes_present = (save_as, hide_all, show_all, toggle_all)\n        context_menu = (\n            *[draw_action for _, draw_action in draw],\n            edit_mode,\n            edit,\n            duplicate,\n            copy,\n            paste,\n            delete,\n            undo,\n            undo_last_point,\n            remove_point,\n        )\n        edit_menu = (\n            edit,\n            duplicate,\n            copy,\n            paste,\n            delete,\n            None,\n            undo,\n            undo_last_point,\n            None,\n            remove_point,\n            None,\n            toggle_keep_prev_mode,\n        )\n        return _Actions(\n            about=about,\n            save=save,\n            save_as=save_as,\n            save_auto=save_auto,\n            save_with_image_data=save_with_image_data,\n            change_output_dir=change_output_dir,\n            open=open_,\n            close=close,\n            delete_file=delete_file,\n            toggle_keep_prev_mode=toggle_keep_prev_mode,\n            toggle_keep_prev_brightness_contrast=toggle_keep_prev_brightness_contrast,\n            delete=delete,\n            edit=edit,\n            duplicate=duplicate,\n            copy=copy,\n            paste=paste,\n            undo_last_point=undo_last_point,\n            undo=undo,\n            remove_point=remove_point,\n            create_mode=create_mode,\n            edit_mode=edit_mode,\n            create_rectangle_mode=create_rectangle_mode,\n            create_circle_mode=create_circle_mode,\n            create_line_mode=create_line_mode,\n            create_point_mode=create_point_mode,\n            create_line_strip_mode=create_line_strip_mode,\n            create_ai_polygon_mode=create_ai_polygon_mode,\n            create_ai_mask_mode=create_ai_mask_mode,\n            open_next_img=open_next_img,\n            open_prev_img=open_prev_img,\n            keep_prev_scale=keep_prev_scale,\n            fit_window=fit_window,\n            fit_width=fit_width,\n            brightness_contrast=brightness_contrast,\n            zoom_in=zoom_in,\n            zoom_out=zoom_out,\n            zoom_org=zoom_org,\n            reset_layout=reset_layout,\n            fill_drawing=fill_drawing,\n            hide_all=hide_all,\n            show_all=show_all,\n            toggle_all=toggle_all,\n            open_dir=open_dir,\n            zoom_widget_action=zoom_widget_action,\n            draw=draw,\n            zoom=zoom,\n            on_load_active=on_load_active,\n            on_shapes_present=on_shapes_present,\n            context_menu=context_menu,\n            edit_menu=edit_menu,\n        )\n\n    def _setup_menus(self) -> _Menus:\n        action = functools.partial(utils.newAction, self)\n        shortcuts = self._config[\"shortcuts\"]\n\n        quit_ = action(\n            text=self.tr(\"&Quit\"),\n            slot=self.close,\n            shortcut=shortcuts[\"quit\"],\n            icon=None,\n            tip=self.tr(\"Quit application\"),\n        )\n        open_config = action(\n            text=self.tr(\"Preferences…\"),\n            slot=self._open_config_file,\n            shortcut=\"Ctrl+,\" if platform.system() == \"Darwin\" else \"Ctrl+Shift+,\",\n            icon=None,\n            tip=self.tr(\"Open config file in text editor\"),\n        )\n        open_config.setMenuRole(QtWidgets.QAction.PreferencesRole)\n        help_ = action(\n            self.tr(\"&Tutorial\"),\n            self.tutorial,\n            icon=\"question.svg\",\n            tip=self.tr(\"Show tutorial page\"),\n        )\n\n        file_menu = self.menu(self.tr(\"&File\"))\n        edit_menu = self.menu(self.tr(\"&Edit\"))\n        view_menu = self.menu(self.tr(\"&View\"))\n        help_menu = self.menu(self.tr(\"&Help\"))\n        recent_files = QtWidgets.QMenu(self.tr(\"Open &Recent\"))\n\n        label_menu = QtWidgets.QMenu()\n        utils.addActions(label_menu, (self._actions.edit, self._actions.delete))\n        self._docks.label_list.setContextMenuPolicy(Qt.CustomContextMenu)\n        self._docks.label_list.customContextMenuRequested.connect(self.popLabelListMenu)\n\n        utils.addActions(\n            file_menu,\n            (\n                self._actions.open,\n                self._actions.open_next_img,\n                self._actions.open_prev_img,\n                self._actions.open_dir,\n                recent_files,\n                self._actions.save,\n                self._actions.save_as,\n                self._actions.save_auto,\n                self._actions.change_output_dir,\n                self._actions.save_with_image_data,\n                self._actions.close,\n                self._actions.delete_file,\n                None,\n                open_config,\n                None,\n                quit_,\n            ),\n        )\n        utils.addActions(help_menu, (help_, self._actions.about))\n        utils.addActions(\n            view_menu,\n            (\n                self._docks.flag_dock.toggleViewAction(),\n                self._docks.label_dock.toggleViewAction(),\n                self._docks.shape_dock.toggleViewAction(),\n                self._docks.file_dock.toggleViewAction(),\n                None,\n                self._actions.reset_layout,\n                None,\n                self._actions.fill_drawing,\n                None,\n                self._actions.hide_all,\n                self._actions.show_all,\n                self._actions.toggle_all,\n                None,\n                self._actions.zoom_in,\n                self._actions.zoom_out,\n                self._actions.zoom_org,\n                self._actions.keep_prev_scale,\n                None,\n                self._actions.fit_window,\n                self._actions.fit_width,\n                None,\n                self._actions.brightness_contrast,\n                self._actions.toggle_keep_prev_brightness_contrast,\n            ),\n        )\n\n        file_menu.aboutToShow.connect(self.updateFileMenu)\n\n        utils.addActions(\n            self._canvas_widgets.canvas.menus[0], self._actions.context_menu\n        )\n        utils.addActions(\n            self._canvas_widgets.canvas.menus[1],\n            (\n                action(\"&Copy here\", self.copyShape),\n                action(\"&Move here\", self.moveShape),\n            ),\n        )\n\n        return _Menus(\n            file=file_menu,\n            edit=edit_menu,\n            view=view_menu,\n            help=help_menu,\n            recent_files=recent_files,\n            label_list=label_menu,\n        )\n\n    def _setup_toolbars(self) -> None:\n        select_ai_model = QtWidgets.QWidgetAction(self)\n        select_ai_model.setDefaultWidget(self._ai_annotation)\n\n        ai_prompt_action = QtWidgets.QWidgetAction(self)\n        ai_prompt_action.setDefaultWidget(self._ai_text)\n\n        self.addToolBar(\n            Qt.TopToolBarArea,\n            ToolBar(\n                title=\"Tools\",\n                actions=[\n                    self._actions.open,\n                    self._actions.open_dir,\n                    self._actions.open_prev_img,\n                    self._actions.open_next_img,\n                    self._actions.save,\n                    self._actions.delete_file,\n                    None,\n                    self._actions.edit_mode,\n                    self._actions.duplicate,\n                    self._actions.delete,\n                    self._actions.undo,\n                    self._actions.brightness_contrast,\n                    None,\n                    self._actions.fit_window,\n                    self._actions.zoom_widget_action,\n                    None,\n                    select_ai_model,\n                    None,\n                    ai_prompt_action,\n                ],\n                font_base=self.font(),\n            ),\n        )\n        self.addToolBar(\n            Qt.LeftToolBarArea,\n            ToolBar(\n                title=\"CreateShapeTools\",\n                actions=[a for _, a in self._actions.draw],\n                orientation=Qt.Vertical,\n                button_style=Qt.ToolButtonTextUnderIcon,\n                font_base=self.font(),\n            ),\n        )\n\n    def _setup_app_state(\n        self,\n        *,\n        output_dir: str | None,\n        filename: str | None,\n    ) -> None:\n        self._output_dir = output_dir\n\n        self._image = QtGui.QImage()\n        self._label_file = None\n        self._image_path = None\n        self._max_recent = 7\n        self._other_data = None\n        self._zoom_values = {}\n        self._brightness_contrast_values = {}\n        self._scroll_values = {\n            Qt.Horizontal: {},\n            Qt.Vertical: {},\n        }\n\n        if self._config[\"file_search\"]:\n            self._docks.file_search.setText(self._config[\"file_search\"])\n\n        self._default_state = self.saveState()\n        #\n        # XXX: Could be completely declarative.\n        # Restore application settings.\n        self.settings = QtCore.QSettings(\"labelme\", \"labelme\")\n        #\n        # Bump this when dock/toolbar layout changes to reset window state\n        # for users upgrading from an older version.\n        SETTINGS_VERSION: int = 1\n        if self.settings.value(\"settingsVersion\", 0, type=int) != SETTINGS_VERSION:\n            self._reset_layout()\n            self.settings.setValue(\"settingsVersion\", SETTINGS_VERSION)\n        #\n        self._recent_files = self.settings.value(\"recentFiles\", []) or []\n        self.resize(self.settings.value(\"window/size\", QtCore.QSize(900, 500)))\n        self.move(self.settings.value(\"window/position\", QtCore.QPoint(0, 0)))\n        self.restoreState(self.settings.value(\"window/state\", QtCore.QByteArray()))\n        # Recover window position when the saved screen is no longer connected.\n        if not any(\n            s.availableGeometry().intersects(self.frameGeometry())\n            for s in QtWidgets.QApplication.screens()\n        ) and (primary_screen := QtWidgets.QApplication.primaryScreen()):\n            self.move(primary_screen.availableGeometry().topLeft())\n\n        if filename:\n            if osp.isdir(filename):\n                self._import_images_from_dir(\n                    root_dir=filename, pattern=self._docks.file_search.text()\n                )\n                self._open_next_image()\n            else:\n                self._load_file(filename=filename)\n        else:\n            self._filename = None\n\n    def _setup_status_bar(self) -> _StatusBarWidgets:\n        message = QtWidgets.QLabel(self.tr(\"%s started.\") % __appname__)\n        stats = StatusStats()\n        self.statusBar().addWidget(message, 1)\n        self.statusBar().addWidget(stats, 0)\n        self.statusBar().show()\n        return _StatusBarWidgets(message=message, stats=stats)\n\n    def _setup_canvas(self) -> _CanvasWidgets:\n        zoom_widget = ZoomWidget()\n\n        canvas = Canvas(\n            epsilon=self._config[\"epsilon\"],\n            double_click=self._config[\"canvas\"][\"double_click\"],\n            num_backups=self._config[\"canvas\"][\"num_backups\"],\n            crosshair=self._config[\"canvas\"][\"crosshair\"],\n        )\n        canvas.zoomRequest.connect(self._zoom_requested)\n        canvas.mouseMoved.connect(self._update_status_stats)\n        canvas.statusUpdated.connect(\n            lambda text: self._status_bar.message.setText(text)\n        )\n\n        scroll_area = QtWidgets.QScrollArea()\n        scroll_area.setWidget(canvas)\n        scroll_area.setWidgetResizable(True)\n        scroll_bars = {\n            Qt.Vertical: scroll_area.verticalScrollBar(),\n            Qt.Horizontal: scroll_area.horizontalScrollBar(),\n        }\n        canvas.scrollRequest.connect(self.scrollRequest)\n\n        canvas.newShape.connect(self.newShape)\n        canvas.shapeMoved.connect(self.setDirty)\n        canvas.selectionChanged.connect(self.shapeSelectionChanged)\n        canvas.drawingPolygon.connect(self.toggleDrawingSensitive)\n\n        self.setCentralWidget(scroll_area)\n\n        return _CanvasWidgets(\n            canvas=canvas,\n            zoom_widget=zoom_widget,\n            scroll_bars=scroll_bars,\n        )\n\n    def _setup_dock_widgets(self) -> _DockWidgets:\n        flag_list = QtWidgets.QListWidget()\n        flag = QtWidgets.QDockWidget(self.tr(\"Flags\"), self)\n        flag.setObjectName(\"Flags\")\n        if self._config[\"flags\"]:\n            self._load_flags(\n                flags={k: False for k in self._config[\"flags\"]},\n                widget=flag_list,\n            )\n        flag.setWidget(flag_list)\n        flag_list.itemChanged.connect(self.setDirty)\n\n        label_list = LabelListWidget()\n        label_list.itemSelectionChanged.connect(self._label_selection_changed)\n        label_list.itemDoubleClicked.connect(self._edit_label)\n        label_list.itemChanged.connect(self.labelItemChanged)\n        label_list.itemDropped.connect(self.labelOrderChanged)\n        shape = QtWidgets.QDockWidget(self.tr(\"Annotation List\"), self)\n        shape.setObjectName(\"Labels\")\n        shape.setWidget(label_list)\n\n        unique_label_list = UniqueLabelQListWidget()\n        unique_label_list.setToolTip(\n            self.tr(\"Select label to start annotating for it. Press 'Esc' to deselect.\")\n        )\n        if self._config[\"labels\"]:\n            for lbl in self._config[\"labels\"]:\n                unique_label_list.add_label_item(\n                    label=lbl,\n                    color=self._get_rgb_by_label(\n                        label=lbl, unique_label_list=unique_label_list\n                    ),\n                )\n        label = QtWidgets.QDockWidget(self.tr(\"Label List\"), self)\n        label.setObjectName(\"Label List\")\n        label.setWidget(unique_label_list)\n\n        file_search = QtWidgets.QLineEdit()\n        file_search.setPlaceholderText(self.tr(\"Search Filename\"))\n        file_search.textChanged.connect(self.fileSearchChanged)\n        file_list = QtWidgets.QListWidget()\n        file_list.itemSelectionChanged.connect(self.fileSelectionChanged)\n        file_list_layout = QtWidgets.QVBoxLayout()\n        file_list_layout.setContentsMargins(0, 0, 0, 0)\n        file_list_layout.setSpacing(0)\n        file_list_layout.addWidget(file_search)\n        file_list_layout.addWidget(file_list)\n        file = QtWidgets.QDockWidget(self.tr(\"File List\"), self)\n        file.setObjectName(\"Files\")\n        file_list_container = QtWidgets.QWidget()\n        file_list_container.setLayout(file_list_layout)\n        file.setWidget(file_list_container)\n\n        for config_key, dock_widget in [\n            (\"flag_dock\", flag),\n            (\"label_dock\", label),\n            (\"shape_dock\", shape),\n            (\"file_dock\", file),\n        ]:\n            features = QtWidgets.QDockWidget.DockWidgetFeatures()\n            if self._config[config_key][\"closable\"]:\n                features = features | QtWidgets.QDockWidget.DockWidgetClosable\n            if self._config[config_key][\"floatable\"]:\n                features = features | QtWidgets.QDockWidget.DockWidgetFloatable\n            if self._config[config_key][\"movable\"]:\n                features = features | QtWidgets.QDockWidget.DockWidgetMovable\n            dock_widget.setFeatures(features)\n            if self._config[config_key][\"show\"] is False:\n                dock_widget.setVisible(False)\n            self.addDockWidget(Qt.RightDockWidgetArea, dock_widget)\n\n        return _DockWidgets(\n            flag_dock=flag,\n            flag_list=flag_list,\n            shape_dock=shape,\n            label_list=label_list,\n            label_dock=label,\n            unique_label_list=unique_label_list,\n            file_dock=file,\n            file_search=file_search,\n            file_list=file_list,\n        )\n\n    def _load_config(\n        self, config_file: Path | None, config_overrides: dict | None\n    ) -> tuple[Path | None, dict]:\n        try:\n            config = load_config(\n                config_file=config_file, config_overrides=config_overrides or {}\n            )\n        except ValueError as e:\n            msg_box = QMessageBox(self)\n            msg_box.setIcon(QMessageBox.Warning)\n            msg_box.setWindowTitle(self.tr(\"Configuration Errors\"))\n            msg_box.setText(\n                self.tr(\n                    \"Errors were found while loading the configuration. \"\n                    \"Please review the errors below and reload your configuration or \"\n                    \"ignore the erroneous lines.\"\n                )\n            )\n            msg_box.setInformativeText(str(e))\n            msg_box.setStandardButtons(QMessageBox.Ignore)\n            msg_box.setModal(False)\n            msg_box.show()\n\n            config_file = None\n            config_overrides = {}\n            config = load_config(\n                config_file=config_file, config_overrides=config_overrides\n            )\n        return config_file, config\n\n    def menu(self, title, actions=None):\n        menu = self.menuBar().addMenu(title)\n        if actions:\n            utils.addActions(menu, actions)\n        return menu\n\n    # Support Functions\n\n    def noShapes(self) -> bool:\n        return not len(self._docks.label_list)\n\n    def populateModeActions(self) -> None:\n        self._canvas_widgets.canvas.menus[0].clear()\n        utils.addActions(\n            self._canvas_widgets.canvas.menus[0], self._actions.context_menu\n        )\n        self._menus.edit.clear()\n        actions = (\n            *[draw_action for _, draw_action in self._actions.draw],\n            self._actions.edit_mode,\n            *self._actions.edit_menu,\n        )\n        utils.addActions(self._menus.edit, actions)\n\n    def _get_window_title(self, dirty: bool) -> str:\n        window_title: str = __appname__\n        if self._image_path:\n            window_title = f\"{window_title} - {self._image_path}\"\n            if self._docks.file_list.count() and self._docks.file_list.currentItem():\n                window_title = (\n                    f\"{window_title} \"\n                    f\"[{self._docks.file_list.currentRow() + 1}\"\n                    f\"/{self._docks.file_list.count()}]\"\n                )\n        if dirty:\n            window_title = f\"{window_title}*\"\n        return window_title\n\n    def setDirty(self) -> None:\n        # Even if we autosave the file, we keep the ability to undo\n        self._actions.undo.setEnabled(self._canvas_widgets.canvas.isShapeRestorable)\n\n        if self._config[\"auto_save\"] or self._actions.save_auto.isChecked():\n            assert self._image_path\n            label_file = f\"{osp.splitext(self._image_path)[0]}.json\"\n            if self._output_dir:\n                label_file_without_path = osp.basename(label_file)\n                label_file = osp.join(self._output_dir, label_file_without_path)\n            self.saveLabels(label_file)\n            return\n        self._is_changed = True\n        self._actions.save.setEnabled(True)\n        self.setWindowTitle(self._get_window_title(dirty=True))\n\n    def setClean(self) -> None:\n        self._is_changed = False\n        self._actions.save.setEnabled(False)\n        for _, action in self._actions.draw:\n            action.setEnabled(True)\n        self.setWindowTitle(self._get_window_title(dirty=False))\n\n        if self.hasLabelFile():\n            self._actions.delete_file.setEnabled(True)\n        else:\n            self._actions.delete_file.setEnabled(False)\n\n    def toggleActions(self, value: bool = True) -> None:\n        \"\"\"Enable/Disable widgets which depend on an opened image.\"\"\"\n        for z in self._actions.zoom:\n            z.setEnabled(value)\n        for action in self._actions.on_load_active:\n            action.setEnabled(value)\n\n    def queueEvent(self, function: Callable[[], None]) -> None:\n        QtCore.QTimer.singleShot(0, function)\n\n    def show_status_message(self, message: str, delay: int = 500) -> None:\n        self.statusBar().showMessage(message, delay)\n\n    def _submit_ai_prompt(self, _) -> None:\n        if (\n            self._canvas_widgets.canvas.createMode\n            not in _AI_TEXT_TO_ANNOTATION_CREATE_MODE_TO_SHAPE_TYPE\n        ):\n            logger.warning(\n                \"Unsupported createMode={!r}\", self._canvas_widgets.canvas.createMode\n            )\n            return\n        shape_type: Literal[\"rectangle\", \"polygon\", \"mask\"] = (\n            _AI_TEXT_TO_ANNOTATION_CREATE_MODE_TO_SHAPE_TYPE[\n                self._canvas_widgets.canvas.createMode\n            ]\n        )\n\n        texts = self._ai_text.get_text_prompt().split(\",\")\n\n        model_name: str = self._ai_text.get_model_name()\n        model_type = osam.apis.get_model_type_by_name(model_name)\n        if not (_is_already_downloaded := model_type.get_size() is not None):\n            if not download_ai_model(model_name=model_name, parent=self):\n                return\n        if (\n            self._text_osam_session is None\n            or self._text_osam_session.model_name != model_name\n        ):\n            self._text_osam_session = OsamSession(model_name=model_name)\n\n        boxes, scores, labels, masks = bbox_from_text.get_bboxes_from_texts(\n            session=self._text_osam_session,\n            image=utils.img_qt_to_arr(self._image)[:, :, :3],\n            image_id=str(hash(self._image_path)),\n            texts=texts,\n        )\n\n        SCORE_FOR_EXISTING_SHAPE: float = 1.01\n        for shape in self._canvas_widgets.canvas.shapes:\n            if shape.shape_type != shape_type or shape.label not in texts:\n                continue\n            points: NDArray[np.float64] = np.array(\n                [[p.x(), p.y()] for p in shape.points]\n            )\n            xmin, ymin = points.min(axis=0)\n            xmax, ymax = points.max(axis=0)\n            box = np.array([xmin, ymin, xmax, ymax], dtype=np.float32)\n            boxes = np.r_[boxes, [box]]\n            scores = np.r_[scores, [SCORE_FOR_EXISTING_SHAPE]]\n            labels = np.r_[labels, [texts.index(shape.label)]]\n\n        boxes, scores, labels, indices = bbox_from_text.nms_bboxes(\n            boxes=boxes,\n            scores=scores,\n            labels=labels,\n            iou_threshold=self._ai_text.get_iou_threshold(),\n            score_threshold=self._ai_text.get_score_threshold(),\n            max_num_detections=100,\n        )\n\n        is_new = scores != SCORE_FOR_EXISTING_SHAPE\n        boxes = boxes[is_new]\n        scores = scores[is_new]\n        labels = labels[is_new]\n        indices = indices[is_new]\n\n        if masks is not None:\n            masks = masks[indices]\n        del indices\n\n        shapes: list[Shape] = bbox_from_text.get_shapes_from_bboxes(\n            boxes=boxes,\n            scores=scores,\n            labels=labels,\n            texts=texts,\n            masks=masks,\n            shape_type=shape_type,\n        )\n\n        self._canvas_widgets.canvas.storeShapes()\n        self._load_shapes(shapes, replace=False)\n        self.setDirty()\n\n    def resetState(self) -> None:\n        self._docks.label_list.clear()\n        self._filename = None\n        self._image_path = None\n        self.imageData = None\n        self._label_file = None\n        self._other_data = None\n        self._canvas_widgets.canvas.resetState()\n\n    def currentItem(self) -> LabelListWidgetItem | None:\n        items = self._docks.label_list.selectedItems()\n        if items:\n            return items[0]\n        return None\n\n    def addRecentFile(self, filename: str) -> None:\n        if filename in self._recent_files:\n            self._recent_files.remove(filename)\n        elif len(self._recent_files) >= self._max_recent:\n            self._recent_files.pop()\n        self._recent_files.insert(0, filename)\n\n    # Callbacks\n\n    def undoShapeEdit(self) -> None:\n        self._canvas_widgets.canvas.restoreShape()\n        self._docks.label_list.clear()\n        self._load_shapes(self._canvas_widgets.canvas.shapes)\n        self._actions.undo.setEnabled(self._canvas_widgets.canvas.isShapeRestorable)\n\n    def tutorial(self):\n        url = \"https://github.com/labelmeai/labelme/tree/main/examples/tutorial\"  # NOQA\n        webbrowser.open(url)\n\n    def toggleDrawingSensitive(self, drawing=True):\n        \"\"\"Toggle drawing sensitive.\n\n        In the middle of drawing, toggling between modes should be disabled.\n        \"\"\"\n        self._actions.edit_mode.setEnabled(not drawing)\n        self._actions.undo_last_point.setEnabled(drawing)\n        self._actions.undo.setEnabled(not drawing)\n        self._actions.delete.setEnabled(not drawing)\n\n    def _switch_canvas_mode(\n        self, edit: bool = True, createMode: str | None = None\n    ) -> None:\n        self._canvas_widgets.canvas.setEditing(edit)\n        if createMode is not None:\n            self._canvas_widgets.canvas.createMode = createMode\n        if edit:\n            for _, draw_action in self._actions.draw:\n                draw_action.setEnabled(True)\n        else:\n            for draw_mode, draw_action in self._actions.draw:\n                draw_action.setEnabled(createMode != draw_mode)\n        self._actions.edit_mode.setEnabled(not edit)\n        self._ai_text.setEnabled(\n            not edit and createMode in _AI_TEXT_TO_ANNOTATION_CREATE_MODE_TO_SHAPE_TYPE\n        )\n        self._ai_annotation.setEnabled(\n            not edit and createMode in (\"ai_polygon\", \"ai_mask\")\n        )\n\n    def updateFileMenu(self):\n        current = self._filename\n\n        def exists(filename):\n            return osp.exists(str(filename))\n\n        menu = self._menus.recent_files\n        menu.clear()\n        files = [f for f in self._recent_files if f != current and exists(f)]\n        for i, f in enumerate(files):\n            icon = utils.newIcon(\"labels\")\n            action = QtWidgets.QAction(\n                icon, f\"&{i + 1} {QtCore.QFileInfo(f).fileName()}\", self\n            )\n            action.triggered.connect(functools.partial(self.loadRecent, f))\n            menu.addAction(action)\n\n    def popLabelListMenu(self, point: QtCore.QPoint) -> None:\n        self._menus.label_list.exec(self._docks.label_list.mapToGlobal(point))  # type: ignore[invalid-argument-type]\n\n    def validateLabel(self, label):\n        # no validation\n        if self._config[\"validate_label\"] is None:\n            return True\n\n        for i in range(self._docks.unique_label_list.count()):\n            label_i = self._docks.unique_label_list.item(i).data(Qt.UserRole)  # type: ignore[attr-defined,union-attr]\n            if self._config[\"validate_label\"] in [\"exact\"]:\n                if label_i == label:\n                    return True\n        return False\n\n    def _edit_label(self, value=None):\n        items = self._docks.label_list.selectedItems()\n        if not items:\n            logger.warning(\"No label is selected, so cannot edit label.\")\n            return\n\n        shape = items[0].shape()\n\n        if len(items) == 1:\n            edit_text = True\n            edit_flags = True\n            edit_group_id = True\n            edit_description = True\n        else:\n            edit_text = all(item.shape().label == shape.label for item in items[1:])\n            edit_flags = all(item.shape().flags == shape.flags for item in items[1:])\n            edit_group_id = all(\n                item.shape().group_id == shape.group_id for item in items[1:]\n            )\n            edit_description = all(\n                item.shape().description == shape.description for item in items[1:]\n            )\n\n        if not edit_text:\n            self._label_dialog.edit.setDisabled(True)\n            self._label_dialog.labelList.setDisabled(True)\n        if not edit_group_id:\n            self._label_dialog.edit_group_id.setDisabled(True)\n        if not edit_description:\n            self._label_dialog.editDescription.setDisabled(True)\n\n        text, flags, group_id, description = self._label_dialog.popUp(\n            text=shape.label if edit_text else \"\",\n            flags=shape.flags if edit_flags else None,\n            group_id=shape.group_id if edit_group_id else None,\n            description=shape.description if edit_description else None,\n            flags_disabled=not edit_flags,\n        )\n\n        if not edit_text:\n            self._label_dialog.edit.setDisabled(False)\n            self._label_dialog.labelList.setDisabled(False)\n        if not edit_group_id:\n            self._label_dialog.edit_group_id.setDisabled(False)\n        if not edit_description:\n            self._label_dialog.editDescription.setDisabled(False)\n\n        if text is None:\n            assert flags is None\n            assert group_id is None\n            assert description is None\n            return\n\n        if not self.validateLabel(text):\n            self.errorMessage(\n                self.tr(\"Invalid label\"),\n                self.tr(\"Invalid label '{}' with validation type '{}'\").format(\n                    text, self._config[\"validate_label\"]\n                ),\n            )\n            return\n\n        self._canvas_widgets.canvas.storeShapes()\n        for item in items:\n            shape: Shape = item.shape()  # type: ignore[no-redef]\n\n            if edit_text:\n                shape.label = text\n            if edit_flags:\n                shape.flags = flags\n            if edit_group_id:\n                shape.group_id = group_id\n            if edit_description:\n                shape.description = description\n\n            self._update_shape_color(shape)\n            if shape.group_id is None:\n                r, g, b = shape.fill_color.getRgb()[:3]\n                item.setText(\n                    f\"{html.escape(shape.label)} \"\n                    f'<font color=\"#{r:02x}{g:02x}{b:02x}\">●</font>'\n                )\n            else:\n                item.setText(f\"{shape.label} ({shape.group_id})\")\n            self.setDirty()\n            if self._docks.unique_label_list.find_label_item(shape.label) is None:\n                self._docks.unique_label_list.add_label_item(\n                    label=shape.label,\n                    color=self._get_rgb_by_label(\n                        label=shape.label,\n                        unique_label_list=self._docks.unique_label_list,\n                    ),\n                )\n\n    def fileSearchChanged(self):\n        self._import_images_from_dir(\n            root_dir=self._prev_opened_dir, pattern=self._docks.file_search.text()\n        )\n\n    def fileSelectionChanged(self) -> None:\n        items = self._docks.file_list.selectedItems()\n        if not items:\n            return\n        item = items[0]\n\n        if not self._can_continue():\n            return\n\n        curr_index = self.imageList.index(str(item.text()))\n        if curr_index < len(self.imageList):\n            filename = self.imageList[curr_index]\n            if filename:\n                self._load_file(filename)\n\n    # React to canvas signals.\n    def shapeSelectionChanged(self, selected_shapes: list[Shape]) -> None:\n        self._docks.label_list.itemSelectionChanged.disconnect(\n            self._label_selection_changed\n        )\n        for shape in self._canvas_widgets.canvas.selectedShapes:\n            shape.selected = False\n        self._docks.label_list.clearSelection()\n        self._canvas_widgets.canvas.selectedShapes = selected_shapes\n        for shape in self._canvas_widgets.canvas.selectedShapes:\n            shape.selected = True\n            item = self._docks.label_list.findItemByShape(shape)\n            self._docks.label_list.selectItem(item)\n            self._docks.label_list.scrollToItem(item)\n        self._docks.label_list.itemSelectionChanged.connect(\n            self._label_selection_changed\n        )\n        n_selected = len(selected_shapes) > 0\n        self._actions.delete.setEnabled(n_selected)\n        self._actions.duplicate.setEnabled(n_selected)\n        self._actions.copy.setEnabled(n_selected)\n        self._actions.edit.setEnabled(n_selected)\n\n    def addLabel(self, shape: Shape) -> None:\n        assert shape.label is not None\n        if shape.group_id is None:\n            text = shape.label\n        else:\n            text = f\"{shape.label} ({shape.group_id})\"\n        label_list_item = LabelListWidgetItem(text, shape)\n        self._docks.label_list.addItem(label_list_item)\n        if self._docks.unique_label_list.find_label_item(shape.label) is None:\n            self._docks.unique_label_list.add_label_item(\n                label=shape.label,\n                color=self._get_rgb_by_label(\n                    label=shape.label,\n                    unique_label_list=self._docks.unique_label_list,\n                ),\n            )\n        self._label_dialog.addLabelHistory(shape.label)\n        for action in self._actions.on_shapes_present:\n            action.setEnabled(True)\n\n        self._update_shape_color(shape)\n        r, g, b = shape.fill_color.getRgb()[:3]\n        label_list_item.setText(\n            f'{html.escape(text)} <font color=\"#{r:02x}{g:02x}{b:02x}\">●</font>'\n        )\n\n    def _update_shape_color(self, shape: Shape) -> None:\n        assert shape.label is not None\n        r, g, b = self._get_rgb_by_label(\n            shape.label, unique_label_list=self._docks.unique_label_list\n        )\n        shape.line_color = QtGui.QColor(r, g, b)\n        shape.vertex_fill_color = QtGui.QColor(r, g, b)\n        shape.hvertex_fill_color = QtGui.QColor(255, 255, 255)\n        shape.fill_color = QtGui.QColor(r, g, b, 128)\n        shape.select_line_color = QtGui.QColor(255, 255, 255)\n        shape.select_fill_color = QtGui.QColor(r, g, b, 155)\n\n    def _get_rgb_by_label(\n        self,\n        label: str,\n        unique_label_list: UniqueLabelQListWidget,\n    ) -> tuple[int, int, int]:\n        if self._config[\"shape_color\"] == \"auto\":\n            item = unique_label_list.find_label_item(label)\n            item_index: int = (\n                unique_label_list.indexFromItem(item).row()\n                if item\n                else unique_label_list.count()\n            )\n            label_id: int = (\n                1  # skip black color by default\n                + item_index\n                + self._config[\"shift_auto_shape_color\"]\n            )\n            rgb: tuple[int, int, int] = tuple(\n                LABEL_COLORMAP[label_id % len(LABEL_COLORMAP)].tolist()\n            )\n            return rgb\n        elif (\n            self._config[\"shape_color\"] == \"manual\"\n            and self._config[\"label_colors\"]\n            and label in self._config[\"label_colors\"]\n        ):\n            if not (\n                len(self._config[\"label_colors\"][label]) == 3\n                and all(0 <= c <= 255 for c in self._config[\"label_colors\"][label])\n            ):\n                raise ValueError(\n                    \"Color for label must be 0-255 RGB tuple, but got: \"\n                    f\"{self._config['label_colors'][label]}\"\n                )\n            return tuple(self._config[\"label_colors\"][label])\n        elif self._config[\"default_shape_color\"]:\n            return self._config[\"default_shape_color\"]\n        return (0, 255, 0)\n\n    def remLabels(self, shapes: list[Shape]) -> None:\n        for shape in shapes:\n            item = self._docks.label_list.findItemByShape(shape)\n            self._docks.label_list.removeItem(item)\n\n    def _load_shapes(self, shapes: list[Shape], replace: bool = True) -> None:\n        self._docks.label_list.itemSelectionChanged.disconnect(\n            self._label_selection_changed\n        )\n        shape: Shape\n        for shape in shapes:\n            self.addLabel(shape)\n        self._docks.label_list.clearSelection()\n        self._docks.label_list.itemSelectionChanged.connect(\n            self._label_selection_changed\n        )\n        self._canvas_widgets.canvas.loadShapes(shapes=shapes, replace=replace)\n\n    def _load_shape_dicts(self, shape_dicts: list[ShapeDict]) -> None:\n        shapes: list[Shape] = []\n        shape_dict: ShapeDict\n        for shape_dict in shape_dicts:\n            shape: Shape = Shape(\n                label=shape_dict[\"label\"],\n                shape_type=shape_dict[\"shape_type\"],\n                group_id=shape_dict[\"group_id\"],\n                description=shape_dict[\"description\"],\n                mask=shape_dict[\"mask\"],\n            )\n            for x, y in shape_dict[\"points\"]:\n                shape.addPoint(QtCore.QPointF(x, y))\n            shape.close()\n\n            default_flags = {}\n            if self._config[\"label_flags\"]:\n                for pattern, keys in self._config[\"label_flags\"].items():\n                    if not isinstance(shape.label, str):\n                        logger.warning(\"shape.label is not str: {}\", shape.label)\n                        continue\n                    if re.match(pattern, shape.label):\n                        for key in keys:\n                            default_flags[key] = False\n            shape.flags = default_flags\n            shape.flags.update(shape_dict[\"flags\"])\n            shape.other_data = shape_dict[\"other_data\"]\n\n            shapes.append(shape)\n        self._load_shapes(shapes=shapes)\n\n    def _load_flags(\n        self,\n        flags: dict[str, bool],\n        widget: QtWidgets.QListWidget,\n    ) -> None:\n        widget.clear()\n        key: str\n        flag: bool\n        for key, flag in flags.items():\n            item: QtWidgets.QListWidgetItem = QtWidgets.QListWidgetItem(key)\n            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)\n            item.setCheckState(Qt.Checked if flag else Qt.Unchecked)\n            widget.addItem(item)\n\n    def saveLabels(self, filename):\n        lf = LabelFile()\n\n        def format_shape(s):\n            data = s.other_data.copy()\n            data.update(\n                dict(\n                    label=s.label,\n                    points=[(p.x(), p.y()) for p in s.points],\n                    group_id=s.group_id,\n                    description=s.description,\n                    shape_type=s.shape_type,\n                    flags=s.flags,\n                    mask=None\n                    if s.mask is None\n                    else utils.img_arr_to_b64(s.mask.astype(np.uint8)),\n                )\n            )\n            return data\n\n        shapes = [format_shape(item.shape()) for item in self._docks.label_list]\n        flags = {}\n        for i in range(self._docks.flag_list.count()):\n            item = self._docks.flag_list.item(i)\n            assert item\n            key = item.text()\n            flag = item.checkState() == Qt.Checked\n            flags[key] = flag\n        try:\n            assert self._image_path\n            imagePath = osp.relpath(self._image_path, osp.dirname(filename))\n            imageData = self.imageData if self._config[\"with_image_data\"] else None\n            if osp.dirname(filename) and not osp.exists(osp.dirname(filename)):\n                os.makedirs(osp.dirname(filename))\n            lf.save(\n                filename=filename,\n                shapes=shapes,\n                imagePath=imagePath,\n                imageData=imageData,\n                imageHeight=self._image.height(),\n                imageWidth=self._image.width(),\n                otherData=self._other_data,\n                flags=flags,\n            )\n            self._label_file = lf\n            items = self._docks.file_list.findItems(self._image_path, Qt.MatchExactly)\n            if len(items) > 0:\n                if len(items) != 1:\n                    raise RuntimeError(\"There are duplicate files.\")\n                items[0].setCheckState(Qt.Checked)\n            # disable allows next and previous image to proceed\n            # self._filename = filename\n            return True\n        except LabelFileError as e:\n            self.errorMessage(\n                self.tr(\"Error saving label data\"), self.tr(\"<b>%s</b>\") % e\n            )\n            return False\n\n    def duplicateSelectedShape(self) -> None:\n        self.copySelectedShape()\n        self.pasteSelectedShape()\n\n    def pasteSelectedShape(self) -> None:\n        self._load_shapes(shapes=self._copied_shapes, replace=False)\n        self._canvas_widgets.canvas.selectShapes(self._copied_shapes)\n        self.setDirty()\n\n    def copySelectedShape(self) -> None:\n        self._copied_shapes = [\n            s.copy() for s in self._canvas_widgets.canvas.selectedShapes\n        ]\n        self._actions.paste.setEnabled(len(self._copied_shapes) > 0)\n\n    def _label_selection_changed(self) -> None:\n        selected_shapes: list[Shape] = []\n        for item in self._docks.label_list.selectedItems():\n            selected_shapes.append(item.shape())\n        if selected_shapes:\n            self._canvas_widgets.canvas.selectShapes(selected_shapes)\n        else:\n            if self._canvas_widgets.canvas.deSelectShape():\n                self._canvas_widgets.canvas.update()\n\n    def labelItemChanged(self, item: LabelListWidgetItem) -> None:\n        shape = item.shape()\n        self._canvas_widgets.canvas.setShapeVisible(\n            shape, item.checkState() == Qt.Checked\n        )\n\n    def labelOrderChanged(self) -> None:\n        self.setDirty()\n        self._canvas_widgets.canvas.loadShapes(\n            [item.shape() for item in self._docks.label_list]\n        )\n\n    # Callback functions:\n\n    def newShape(self) -> None:\n        \"\"\"Pop-up and give focus to the label editor.\n\n        position MUST be in global coordinates.\n        \"\"\"\n        items = self._docks.unique_label_list.selectedItems()\n        text = None\n        if items:\n            text = items[0].data(Qt.UserRole)\n        flags = {}\n        group_id = None\n        description = \"\"\n        if self._config[\"display_label_popup\"] or not text:\n            previous_text = self._label_dialog.edit.text()\n            text, flags, group_id, description = self._label_dialog.popUp(text)\n            if not text:\n                self._label_dialog.edit.setText(previous_text)\n\n        if text and not self.validateLabel(text):\n            self.errorMessage(\n                self.tr(\"Invalid label\"),\n                self.tr(\"Invalid label '{}' with validation type '{}'\").format(\n                    text, self._config[\"validate_label\"]\n                ),\n            )\n            text = \"\"\n        if text:\n            self._docks.label_list.clearSelection()\n            shape = self._canvas_widgets.canvas.setLastLabel(text, flags)\n            shape.group_id = group_id\n            shape.description = description\n            self.addLabel(shape)\n            self._actions.edit_mode.setEnabled(True)\n            self._actions.undo_last_point.setEnabled(False)\n            self._actions.undo.setEnabled(True)\n            self.setDirty()\n        else:\n            self._canvas_widgets.canvas.undoLastLine()\n            self._canvas_widgets.canvas.shapesBackups.pop()\n\n    def scrollRequest(self, delta: int, orientation: Qt.Orientation) -> None:\n        units = -delta * 0.1  # natural scroll\n        bar = self._canvas_widgets.scroll_bars[orientation]\n        value = bar.value() + bar.singleStep() * units\n        self.setScroll(orientation, value)\n\n    def setScroll(self, orientation: Qt.Orientation, value: float) -> None:\n        self._canvas_widgets.scroll_bars[orientation].setValue(int(value))\n        if self._filename is not None:\n            self._scroll_values[orientation][self._filename] = value\n\n    def _set_zoom(self, value: int, pos: QtCore.QPointF | None = None) -> None:\n        if self._filename is None:\n            logger.warning(\"filename is None, cannot set zoom\")\n            return\n\n        if pos is None:\n            pos = QtCore.QPointF(\n                self._canvas_widgets.canvas.visibleRegion().boundingRect().center()\n            )\n        canvas_width_old: int = self._canvas_widgets.canvas.width()\n\n        self._actions.fit_width.setChecked(self._zoom_mode == _ZoomMode.FIT_WIDTH)\n        self._actions.fit_window.setChecked(self._zoom_mode == _ZoomMode.FIT_WINDOW)\n        self._canvas_widgets.canvas.enableDragging(\n            enabled=value > int(self._scalers[_ZoomMode.FIT_WINDOW]() * 100)\n        )\n        self._canvas_widgets.zoom_widget.setValue(value)  # triggers self._paint_canvas\n        self._zoom_values[self._filename] = (self._zoom_mode, value)\n\n        canvas_width_new: int = self._canvas_widgets.canvas.width()\n        if canvas_width_old == canvas_width_new:\n            return\n        canvas_scale_factor = canvas_width_new / canvas_width_old\n        x_shift: float = pos.x() * canvas_scale_factor - pos.x()\n        y_shift: float = pos.y() * canvas_scale_factor - pos.y()\n        self.setScroll(\n            Qt.Horizontal,\n            self._canvas_widgets.scroll_bars[Qt.Horizontal].value() + x_shift,\n        )\n        self.setScroll(\n            Qt.Vertical,\n            self._canvas_widgets.scroll_bars[Qt.Vertical].value() + y_shift,\n        )\n\n    def _set_zoom_to_original(self):\n        self._zoom_mode = _ZoomMode.MANUAL_ZOOM\n        self._set_zoom(value=100)\n\n    def _add_zoom(self, increment: float, pos: QtCore.QPointF | None = None) -> None:\n        zoom_value: int\n        if increment > 1:\n            zoom_value = math.ceil(self._canvas_widgets.zoom_widget.value() * increment)\n        else:\n            zoom_value = math.floor(\n                self._canvas_widgets.zoom_widget.value() * increment\n            )\n        self._zoom_mode = _ZoomMode.MANUAL_ZOOM\n        self._set_zoom(value=zoom_value, pos=pos)\n\n    def _zoom_requested(self, delta: int, pos: QtCore.QPointF) -> None:\n        self._add_zoom(increment=1.1 if delta > 0 else 0.9, pos=pos)\n\n    def setFitWindow(self, value=True):\n        if value:\n            self._actions.fit_width.setChecked(False)\n        self._zoom_mode = _ZoomMode.FIT_WINDOW if value else _ZoomMode.MANUAL_ZOOM\n        self._adjust_scale()\n\n    def setFitWidth(self, value=True):\n        if value:\n            self._actions.fit_window.setChecked(False)\n        self._zoom_mode = _ZoomMode.FIT_WIDTH if value else _ZoomMode.MANUAL_ZOOM\n        self._adjust_scale()\n\n    def enableKeepPrevScale(self, enabled):\n        self._config[\"keep_prev_scale\"] = enabled\n        self._actions.keep_prev_scale.setChecked(enabled)\n\n    def onNewBrightnessContrast(self, qimage):\n        self._canvas_widgets.canvas.loadPixmap(\n            QtGui.QPixmap.fromImage(qimage), clear_shapes=False\n        )\n\n    def brightnessContrast(self, value: bool, is_initial_load: bool = False):\n        if self._filename is None:\n            logger.warning(\"filename is None, cannot set brightness/contrast\")\n            return\n\n        brightness: int | None\n        contrast: int | None\n        brightness, contrast = self._brightness_contrast_values.get(\n            self._filename, (None, None)\n        )\n        if is_initial_load:\n            prev_filename: str = self._recent_files[0] if self._recent_files else \"\"\n            if self._config[\"keep_prev_brightness_contrast\"] and prev_filename:\n                brightness, contrast = self._brightness_contrast_values.get(\n                    prev_filename, (None, None)\n                )\n            if brightness is None and contrast is None:\n                return\n\n        logger.debug(\n            \"Opening brightness/contrast dialog with brightness={}, contrast={}\",\n            brightness,\n            contrast,\n        )\n        dialog = BrightnessContrastDialog(\n            utils.img_data_to_pil(self.imageData),\n            self.onNewBrightnessContrast,\n            parent=self,\n        )\n\n        if brightness is not None:\n            dialog.slider_brightness.setValue(brightness)\n        if contrast is not None:\n            dialog.slider_contrast.setValue(contrast)\n\n        if is_initial_load:\n            dialog.onNewValue(None)\n        else:\n            dialog.exec_()\n            brightness = dialog.slider_brightness.value()\n            contrast = dialog.slider_contrast.value()\n\n        self._brightness_contrast_values[self._filename] = (brightness, contrast)\n        logger.debug(\n            \"Updated states for {}: brightness={}, contrast={}\",\n            self._filename,\n            brightness,\n            contrast,\n        )\n\n    def toggleShapes(self, value):\n        flag = value\n        for item in self._docks.label_list:\n            if value is None:\n                flag = item.checkState() == Qt.Unchecked\n            item.setCheckState(Qt.Checked if flag else Qt.Unchecked)\n\n    def _load_file(self, filename=None):\n        \"\"\"Load the specified file, or the last opened file if None.\"\"\"\n        # changing fileListWidget loads file\n        if filename in self.imageList and (\n            self._docks.file_list.currentRow() != self.imageList.index(filename)\n        ):\n            self._docks.file_list.setCurrentRow(self.imageList.index(filename))\n            self._docks.file_list.repaint()\n            return\n\n        prev_shapes: list[Shape] = (\n            self._canvas_widgets.canvas.shapes\n            if self._config[\"keep_prev\"]\n            or QtWidgets.QApplication.keyboardModifiers()\n            == (Qt.ControlModifier | Qt.ShiftModifier)\n            else []\n        )\n        self.resetState()\n        self._canvas_widgets.canvas.setEnabled(False)\n        if filename is None:\n            filename = self.settings.value(\"filename\", \"\")\n        filename = str(filename)\n        if not QtCore.QFile.exists(filename):\n            self.errorMessage(\n                self.tr(\"Error opening file\"),\n                self.tr(\"No such file: <b>%s</b>\") % filename,\n            )\n            return False\n        # assumes same name, but json extension\n        self.show_status_message(self.tr(\"Loading %s...\") % osp.basename(str(filename)))\n        t0_load_file = time.time()\n        label_file = f\"{osp.splitext(filename)[0]}.json\"\n        if self._output_dir:\n            label_file_without_path = osp.basename(label_file)\n            label_file = osp.join(self._output_dir, label_file_without_path)\n        if QtCore.QFile.exists(label_file) and LabelFile.is_label_file(label_file):\n            try:\n                self._label_file = LabelFile(label_file)\n            except LabelFileError as e:\n                self.errorMessage(\n                    self.tr(\"Error opening file\"),\n                    self.tr(\n                        \"<p><b>%s</b></p>\"\n                        \"<p>Make sure <i>%s</i> is a valid label file.</p>\"\n                    )\n                    % (e, label_file),\n                )\n                self.show_status_message(self.tr(\"Error reading %s\") % label_file)\n                return False\n            assert self._label_file is not None\n            self.imageData = self._label_file.imageData\n            assert self._label_file.imagePath\n            self._image_path = osp.join(\n                osp.dirname(label_file),\n                self._label_file.imagePath,\n            )\n            self._other_data = self._label_file.otherData\n        else:\n            try:\n                self.imageData = LabelFile.load_image_file(filename)\n            except OSError as e:\n                self.errorMessage(\n                    self.tr(\"Error opening file\"),\n                    self.tr(\n                        \"<p><b>%s</b></p>\"\n                        \"<p>Make sure <i>%s</i> is a valid image file.</p>\"\n                    )\n                    % (e, filename),\n                )\n                self.show_status_message(self.tr(\"Error reading %s\") % filename)\n                return False\n            if self.imageData:\n                self._image_path = filename\n            self._label_file = None\n        assert self.imageData is not None\n        t0 = time.time()\n        image = QtGui.QImage.fromData(self.imageData)\n        logger.debug(\"Created QImage in {:.0f}ms\", (time.time() - t0) * 1000)\n\n        if image.isNull():\n            formats = [\n                f\"*.{fmt.data().decode()}\"\n                for fmt in QtGui.QImageReader.supportedImageFormats()\n            ]\n            self.errorMessage(\n                self.tr(\"Error opening file\"),\n                self.tr(\n                    \"<p>Make sure <i>{0}</i> is a valid image file.<br/>\"\n                    \"Supported image formats: {1}</p>\"\n                ).format(filename, \",\".join(formats)),\n            )\n            self.show_status_message(self.tr(\"Error reading %s\") % filename)\n            return False\n        self._image = image\n        self._filename = filename\n        t0 = time.time()\n        self._canvas_widgets.canvas.loadPixmap(QtGui.QPixmap.fromImage(image))\n        logger.debug(\"Loaded pixmap in {:.0f}ms\", (time.time() - t0) * 1000)\n        flags = {k: False for k in self._config[\"flags\"] or []}\n        if self._label_file:\n            self._load_shape_dicts(shape_dicts=self._label_file.shapes)\n            if self._label_file.flags is not None:\n                flags.update(self._label_file.flags)\n        self._load_flags(flags=flags, widget=self._docks.flag_list)\n        if prev_shapes and self.noShapes():\n            self._load_shapes(shapes=prev_shapes, replace=False)\n            self.setDirty()\n        else:\n            self.setClean()\n        self._canvas_widgets.canvas.setEnabled(True)\n        # set zoom values\n        is_initial_load = not self._zoom_values\n        if self._filename in self._zoom_values:\n            self._zoom_mode = self._zoom_values[self._filename][0]\n            self._set_zoom(self._zoom_values[self._filename][1])\n        elif is_initial_load or not self._config[\"keep_prev_scale\"]:\n            self._zoom_mode = _ZoomMode.FIT_WINDOW\n            self._adjust_scale()\n        # set scroll values\n        for orientation in self._scroll_values:\n            if self._filename in self._scroll_values[orientation]:\n                self.setScroll(\n                    orientation, self._scroll_values[orientation][self._filename]\n                )\n        self.brightnessContrast(value=False, is_initial_load=True)\n        self._paint_canvas()\n        self.addRecentFile(self._filename)\n        self.toggleActions(True)\n        self._canvas_widgets.canvas.setFocus()\n        self.show_status_message(self.tr(\"Loaded %s\") % osp.basename(filename))\n        logger.info(\n            \"Loaded file: {!r} in {:.0f}ms\",\n            filename,\n            (time.time() - t0_load_file) * 1000,\n        )\n        return True\n\n    def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:\n        if (\n            self._canvas_widgets.canvas\n            and not self._image.isNull()\n            and self._zoom_mode != _ZoomMode.MANUAL_ZOOM\n        ):\n            self._adjust_scale()\n        super().resizeEvent(a0)\n\n    def _paint_canvas(self) -> None:\n        if self._image.isNull():\n            logger.warning(\"image is null, cannot paint canvas\")\n            return\n        self._canvas_widgets.canvas.scale = (\n            0.01 * self._canvas_widgets.zoom_widget.value()\n        )\n        self._canvas_widgets.canvas.adjustSize()\n        self._canvas_widgets.canvas.update()\n\n    def _adjust_scale(self) -> None:\n        self._set_zoom(value=int(self._scalers[self._zoom_mode]() * 100))\n\n    def scaleFitWindow(self) -> float:\n        EPSILON_TO_HIDE_SCROLLBAR: float = 2.0\n        w1: float = self.centralWidget().width() - EPSILON_TO_HIDE_SCROLLBAR\n        h1: float = self.centralWidget().height() - EPSILON_TO_HIDE_SCROLLBAR\n        a1: float = w1 / h1\n\n        w2: float = self._canvas_widgets.canvas.pixmap.width()\n        h2: float = self._canvas_widgets.canvas.pixmap.height()\n        a2: float = w2 / h2\n\n        return w1 / w2 if a2 >= a1 else h1 / h2\n\n    def scaleFitWidth(self):\n        EPSILON_TO_HIDE_SCROLLBAR: float = 15.0\n        w = self.centralWidget().width() - EPSILON_TO_HIDE_SCROLLBAR\n        return w / self._canvas_widgets.canvas.pixmap.width()\n\n    def enableSaveImageWithData(self, enabled):\n        self._config[\"with_image_data\"] = enabled\n        self._actions.save_with_image_data.setChecked(enabled)\n\n    def _reset_layout(self):\n        self.settings.remove(\"window/state\")\n        self.restoreState(self._default_state)\n\n    def closeEvent(self, a0: QtGui.QCloseEvent) -> None:\n        if not self._can_continue():\n            a0.ignore()\n        self.settings.setValue(\"filename\", self._filename if self._filename else \"\")\n        self.settings.setValue(\"window/size\", self.size())\n        self.settings.setValue(\"window/position\", self.pos())\n        self.settings.setValue(\"window/state\", self.saveState())\n        self.settings.setValue(\"recentFiles\", self._recent_files)\n\n    def dragEnterEvent(self, a0: QtGui.QDragEnterEvent) -> None:\n        extensions = [\n            f\".{fmt.data().decode().lower()}\"\n            for fmt in QtGui.QImageReader.supportedImageFormats()\n        ]\n        if a0.mimeData().hasUrls():\n            items = [i.toLocalFile() for i in a0.mimeData().urls()]\n            if any([i.lower().endswith(tuple(extensions)) for i in items]):\n                a0.accept()\n        else:\n            a0.ignore()\n\n    def dropEvent(self, a0: QtGui.QDropEvent) -> None:\n        if not self._can_continue():\n            a0.ignore()\n            return\n        items = [i.toLocalFile() for i in a0.mimeData().urls()]\n        self.importDroppedImageFiles(items)\n\n    # User Dialogs #\n\n    def loadRecent(self, filename):\n        if self._can_continue():\n            self._load_file(filename)\n\n    def _open_prev_image(self, _value=False) -> None:\n        row_prev: int = self._docks.file_list.currentRow() - 1\n        if row_prev < 0:\n            logger.debug(\"there is no prev image\")\n            return\n\n        logger.debug(\"setting current row to {:d}\", row_prev)\n        self._docks.file_list.setCurrentRow(row_prev)\n        self._docks.file_list.repaint()\n\n    def _open_next_image(self, _value=False) -> None:\n        row_next: int = self._docks.file_list.currentRow() + 1\n        if row_next >= self._docks.file_list.count():\n            logger.debug(\"there is no next image\")\n            return\n\n        logger.debug(\"setting current row to {:d}\", row_next)\n        self._docks.file_list.setCurrentRow(row_next)\n        self._docks.file_list.repaint()\n\n    def _open_file_with_dialog(self, _value: bool = False) -> None:\n        if not self._can_continue():\n            return\n        path = osp.dirname(str(self._filename)) if self._filename else \".\"\n        formats = [\n            f\"*.{fmt.data().decode()}\"\n            for fmt in QtGui.QImageReader.supportedImageFormats()\n        ]\n        filters = self.tr(\"Image & Label files (%s)\") % \" \".join(\n            formats + [f\"*{LabelFile.suffix}\"]\n        )\n        fileDialog = FileDialogPreview(self)\n        fileDialog.setFileMode(FileDialogPreview.ExistingFile)\n        fileDialog.setNameFilter(filters)\n        fileDialog.setWindowTitle(\n            self.tr(\"%s - Choose Image or Label file\") % __appname__,\n        )\n        fileDialog.setWindowFilePath(path)\n        fileDialog.setViewMode(FileDialogPreview.Detail)\n        if fileDialog.exec_():\n            fileName = fileDialog.selectedFiles()[0]\n            if fileName:\n                self._load_file(fileName)\n\n    def changeOutputDirDialog(self, _value=False):\n        default_output_dir = self._output_dir\n        if default_output_dir is None and self._filename:\n            default_output_dir = osp.dirname(self._filename)\n        if default_output_dir is None:\n            default_output_dir = self.currentPath()\n\n        output_dir = QtWidgets.QFileDialog.getExistingDirectory(\n            self,\n            self.tr(\"%s - Save/Load Annotations in Directory\") % __appname__,\n            default_output_dir,\n            QtWidgets.QFileDialog.ShowDirsOnly\n            | QtWidgets.QFileDialog.DontResolveSymlinks,\n        )\n        output_dir = str(output_dir)\n\n        if not output_dir:\n            return\n\n        self._output_dir = output_dir\n\n        self.statusBar().showMessage(\n            self.tr(\"%s . Annotations will be saved/loaded in %s\")\n            % (\"Change Annotations Dir\", self._output_dir)\n        )\n        self.statusBar().show()\n\n        current_filename = self._filename\n        self._import_images_from_dir(root_dir=self._prev_opened_dir)\n\n        if current_filename in self.imageList:\n            # retain currently selected file\n            self._docks.file_list.setCurrentRow(self.imageList.index(current_filename))\n            self._docks.file_list.repaint()\n\n    def saveFile(self, _value: bool = False) -> None:\n        assert not self._image.isNull(), \"cannot save empty image\"\n        if self._label_file:\n            self._saveFile(self._label_file.filename)\n        else:\n            self._saveFile(self.saveFileDialog())\n\n    def saveFileAs(self, _value: bool = False) -> None:\n        assert not self._image.isNull(), \"cannot save empty image\"\n        self._saveFile(self.saveFileDialog())\n\n    def saveFileDialog(self) -> str:\n        assert self._filename is not None\n        caption = self.tr(\"%s - Choose File\") % __appname__\n        filters = self.tr(\"Label files (*%s)\") % LabelFile.suffix\n        start_dir = self._output_dir if self._output_dir else self.currentPath()\n        dlg = QtWidgets.QFileDialog(self, caption, start_dir, filters)\n        dlg.setDefaultSuffix(LabelFile.suffix[1:])\n        dlg.setAcceptMode(QtWidgets.QFileDialog.AcceptSave)\n        dlg.setOption(QtWidgets.QFileDialog.DontConfirmOverwrite, False)\n        dlg.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, False)\n        basename = osp.basename(osp.splitext(self._filename)[0])\n        if self._output_dir:\n            default_labelfile_name = osp.join(\n                self._output_dir, basename + LabelFile.suffix\n            )\n        else:\n            default_labelfile_name = osp.join(\n                self.currentPath(), basename + LabelFile.suffix\n            )\n        filename = dlg.getSaveFileName(\n            self,\n            self.tr(\"Choose File\"),\n            default_labelfile_name,\n            self.tr(\"Label files (*%s)\") % LabelFile.suffix,\n        )\n        if isinstance(filename, tuple):\n            return filename[0]\n        return filename\n\n    def _saveFile(self, filename: str | None) -> None:\n        if filename and self.saveLabels(filename):\n            self.addRecentFile(filename)\n            self.setClean()\n\n    def closeFile(self, _value: bool = False) -> None:\n        if not self._can_continue():\n            return\n        self.resetState()\n        self.setClean()\n        self.toggleActions(False)\n        self._canvas_widgets.canvas.setEnabled(False)\n        self._docks.file_list.setFocus()\n        self._actions.save_as.setEnabled(False)\n\n    def getLabelFile(self) -> str:\n        assert self._filename is not None\n        if self._filename.lower().endswith(\".json\"):\n            return self._filename\n        return f\"{osp.splitext(self._filename)[0]}.json\"\n\n    def deleteFile(self) -> None:\n        mb = QtWidgets.QMessageBox\n        msg = self.tr(\n            \"You are about to permanently delete this label file, proceed anyway?\"\n        )\n        answer = mb.warning(self, self.tr(\"Attention\"), msg, mb.Yes | mb.No)\n        if answer != mb.Yes:\n            return\n\n        label_file = self.getLabelFile()\n        if osp.exists(label_file):\n            os.remove(label_file)\n            logger.info(f\"Label file is removed: {label_file}\")\n\n            item = self._docks.file_list.currentItem()\n            if item:\n                item.setCheckState(Qt.Unchecked)\n\n            self.resetState()\n\n    def _open_config_file(self) -> None:\n        if self._config_file is None:\n            QtWidgets.QMessageBox.information(\n                self,\n                self.tr(\"No Config File\"),\n                self.tr(\n                    \"Configuration was provided as a YAML expression via \"\n                    \"command line.\\n\\n\"\n                    \"To use the preferences editor, start Labelme with a config file:\\n\"\n                    \"  labelme --config ~/.labelmerc\"\n                ),\n            )\n            return\n        config_file: Path = self._config_file\n\n        system: str = platform.system()\n        if system == \"Darwin\":\n            subprocess.Popen([\"open\", \"-t\", config_file])\n        elif system == \"Windows\":\n            os.startfile(config_file)  # type: ignore[attr-defined]\n        else:\n            subprocess.Popen([\"xdg-open\", config_file])\n\n    # Message Dialogs. #\n    def hasLabels(self) -> bool:\n        if self.noShapes():\n            self.errorMessage(\n                \"No objects labeled\",\n                \"You must label at least one object to save the file.\",\n            )\n            return False\n        return True\n\n    def hasLabelFile(self) -> bool:\n        if self._filename is None:\n            return False\n\n        label_file = self.getLabelFile()\n        return osp.exists(label_file)\n\n    def _can_continue(self) -> bool:\n        if not self._is_changed:\n            return True\n        mb = QtWidgets.QMessageBox\n        msg = self.tr('Save annotations to \"{}\" before closing?').format(self._filename)\n        answer = mb.question(\n            self,\n            self.tr(\"Save annotations?\"),\n            msg,\n            mb.Save | mb.Discard | mb.Cancel,\n            mb.Save,\n        )\n        if answer == mb.Discard:\n            return True\n        elif answer == mb.Save:\n            self.saveFile()\n            return True\n        else:  # answer == mb.Cancel\n            return False\n\n    def errorMessage(self, title: str, message: str) -> int:\n        return QtWidgets.QMessageBox.critical(\n            self, title, f\"<p><b>{title}</b></p>{message}\"\n        )\n\n    def currentPath(self) -> str:\n        return osp.dirname(str(self._filename)) if self._filename else \".\"\n\n    def toggleKeepPrevMode(self) -> None:\n        self._config[\"keep_prev\"] = not self._config[\"keep_prev\"]\n\n    def removeSelectedPoint(self) -> None:\n        self._canvas_widgets.canvas.removeSelectedPoint()\n        self._canvas_widgets.canvas.update()\n        if (\n            self._canvas_widgets.canvas.hShape\n            and not self._canvas_widgets.canvas.hShape.points\n        ):\n            self._canvas_widgets.canvas.deleteShape(self._canvas_widgets.canvas.hShape)\n            self.remLabels([self._canvas_widgets.canvas.hShape])\n            if self.noShapes():\n                for action in self._actions.on_shapes_present:\n                    action.setEnabled(False)\n        self.setDirty()\n\n    def deleteSelectedShape(self) -> None:\n        yes, no = QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No\n        msg = self.tr(\n            \"You are about to permanently delete {} shapes, proceed anyway?\"\n        ).format(len(self._canvas_widgets.canvas.selectedShapes))\n        if yes == QtWidgets.QMessageBox.warning(\n            self, self.tr(\"Attention\"), msg, yes | no, yes\n        ):\n            self.remLabels(self._canvas_widgets.canvas.deleteSelected())\n            self.setDirty()\n            if self.noShapes():\n                for action in self._actions.on_shapes_present:\n                    action.setEnabled(False)\n\n    def copyShape(self) -> None:\n        self._canvas_widgets.canvas.endMove(copy=True)\n        for shape in self._canvas_widgets.canvas.selectedShapes:\n            self.addLabel(shape)\n        self._docks.label_list.clearSelection()\n        self.setDirty()\n\n    def moveShape(self) -> None:\n        self._canvas_widgets.canvas.endMove(copy=False)\n        self.setDirty()\n\n    def _open_dir_with_dialog(self, _value: bool = False) -> None:\n        if not self._can_continue():\n            return\n\n        defaultOpenDirPath: str\n        if self._prev_opened_dir and osp.exists(self._prev_opened_dir):\n            defaultOpenDirPath = self._prev_opened_dir\n        else:\n            defaultOpenDirPath = osp.dirname(self._filename) if self._filename else \".\"\n\n        targetDirPath = str(\n            QtWidgets.QFileDialog.getExistingDirectory(\n                self,\n                self.tr(\"%s - Open Directory\") % __appname__,\n                defaultOpenDirPath,\n                QtWidgets.QFileDialog.ShowDirsOnly\n                | QtWidgets.QFileDialog.DontResolveSymlinks,\n            )\n        )\n        self._import_images_from_dir(root_dir=targetDirPath)\n        self._open_next_image()\n\n    @property\n    def imageList(self) -> list[str]:\n        lst = []\n        for i in range(self._docks.file_list.count()):\n            item = self._docks.file_list.item(i)\n            assert item\n            lst.append(item.text())\n        return lst\n\n    def importDroppedImageFiles(self, imageFiles):\n        extensions = [\n            f\".{fmt.data().decode().lower()}\"\n            for fmt in QtGui.QImageReader.supportedImageFormats()\n        ]\n\n        self._filename = None\n        for file in imageFiles:\n            if file in self.imageList or not file.lower().endswith(tuple(extensions)):\n                continue\n            label_file = f\"{osp.splitext(file)[0]}.json\"\n            if self._output_dir:\n                label_file_without_path = osp.basename(label_file)\n                label_file = osp.join(self._output_dir, label_file_without_path)\n            item = QtWidgets.QListWidgetItem(file)\n            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)\n            if QtCore.QFile.exists(label_file) and LabelFile.is_label_file(label_file):\n                item.setCheckState(Qt.Checked)\n            else:\n                item.setCheckState(Qt.Unchecked)\n            self._docks.file_list.addItem(item)\n\n        if len(self.imageList) > 1:\n            self._actions.open_next_img.setEnabled(True)\n            self._actions.open_prev_img.setEnabled(True)\n\n        self._open_next_image()\n\n    def _import_images_from_dir(\n        self, root_dir: str | None, pattern: str | None = None\n    ) -> None:\n        self._actions.open_next_img.setEnabled(True)\n        self._actions.open_prev_img.setEnabled(True)\n\n        if not self._can_continue() or not root_dir:\n            return\n\n        self._prev_opened_dir = root_dir\n        self._filename = None\n        self._docks.file_list.clear()\n\n        filenames = _scan_image_files(root_dir=root_dir)\n        if pattern:\n            try:\n                filenames = [f for f in filenames if re.search(pattern, f)]\n            except re.error:\n                pass\n        for filename in filenames:\n            label_file = f\"{osp.splitext(filename)[0]}.json\"\n            if self._output_dir:\n                label_file_without_path = osp.basename(label_file)\n                label_file = osp.join(self._output_dir, label_file_without_path)\n            item = QtWidgets.QListWidgetItem(filename)\n            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)\n            if QtCore.QFile.exists(label_file) and LabelFile.is_label_file(label_file):\n                item.setCheckState(Qt.Checked)\n            else:\n                item.setCheckState(Qt.Unchecked)\n            self._docks.file_list.addItem(item)\n\n    def _update_status_stats(self, mouse_pos: QtCore.QPointF) -> None:\n        stats: list[str] = []\n        stats.append(f\"mode={self._canvas_widgets.canvas.mode.name}\")\n        stats.append(f\"x={mouse_pos.x():6.1f}, y={mouse_pos.y():6.1f}\")\n        self._status_bar.stats.setText(\" | \".join(stats))\n\n\ndef _scan_image_files(root_dir: str) -> list[str]:\n    extensions: list[str] = [\n        f\".{fmt.data().decode().lower()}\"\n        for fmt in QtGui.QImageReader.supportedImageFormats()\n    ]\n\n    images: list[str] = []\n    for root, dirs, files in os.walk(root_dir):\n        for file in files:\n            if file.lower().endswith(tuple(extensions)):\n                relativePath = os.path.normpath(osp.join(root, file))\n                images.append(relativePath)\n\n    logger.debug(\"found {:d} images in {!r}\", len(images), root_dir)\n    return natsort.os_sorted(images)\n"
  },
  {
    "path": "labelme/config/__init__.py",
    "content": "import os.path as osp\nimport re\nfrom pathlib import Path\n\nimport yaml\nfrom loguru import logger\n\nhere = osp.dirname(osp.abspath(__file__))\n\n\ndef _update_dict(target_dict, new_dict, validate_item=None):\n    for key, value in new_dict.items():\n        if validate_item:\n            validate_item(key, value)\n        if key not in target_dict:\n            raise ValueError(f\"Unexpected key in config: {key}\")\n        if isinstance(target_dict[key], dict) and isinstance(value, dict):\n            _update_dict(target_dict[key], value, validate_item=validate_item)\n        else:\n            target_dict[key] = value\n\n\ndef _validate_config_item(key, value):\n    if key == \"validate_label\" and value not in [None, \"exact\"]:\n        raise ValueError(f\"Unexpected value for config key 'validate_label': {value}\")\n    if key == \"shape_color\" and value not in [None, \"auto\", \"manual\"]:\n        raise ValueError(f\"Unexpected value for config key 'shape_color': {value}\")\n    if key == \"labels\" and value is not None and len(value) != len(set(value)):\n        raise ValueError(f\"Duplicates are detected for config key 'labels': {value}\")\n\n\ndef _migrate_config_from_file(config_from_yaml: dict) -> None:\n    keep_prev_brightness: bool = config_from_yaml.pop(\"keep_prev_brightness\", False)\n    keep_prev_contrast: bool = config_from_yaml.pop(\"keep_prev_contrast\", False)\n    if keep_prev_brightness or keep_prev_contrast:\n        logger.info(\n            \"Migrating old config: keep_prev_brightness={} or keep_prev_contrast={} \"\n            \"-> keep_prev_brightness_contrast=True\",\n            keep_prev_brightness,\n            keep_prev_contrast,\n        )\n        config_from_yaml[\"keep_prev_brightness_contrast\"] = True\n\n    if \"store_data\" in config_from_yaml:\n        logger.info(\"Migrating old config: store_data -> with_image_data\")\n        config_from_yaml[\"with_image_data\"] = config_from_yaml.pop(\"store_data\")\n\n    if config_from_yaml.get(\"shortcuts\", {}).pop(\"add_point_to_edge\", None):\n        logger.info(\"Migrating old config: removing shortcuts.add_point_to_edge\")\n\n    if (model_name := config_from_yaml.get(\"ai\", {}).get(\"default\")) and (\n        m := re.match(r\"^SegmentAnything \\((.*)\\)$\", model_name)\n    ):\n        model_name_new: str = f\"Sam ({m.group(1)})\"\n        logger.info(\n            \"Migrating old config: ai.default={!r} -> ai.default={!r}\",\n            model_name,\n            model_name_new,\n        )\n        config_from_yaml[\"ai\"][\"default\"] = model_name_new\n\n    # Migrate polygon shortcut keys to shape\n    _POLYGON_TO_SHAPE_RENAMES = {\n        \"edit_polygon\": \"edit_shape\",\n        \"delete_polygon\": \"delete_shape\",\n        \"duplicate_polygon\": \"duplicate_shape\",\n        \"copy_polygon\": \"copy_shape\",\n        \"paste_polygon\": \"paste_shape\",\n        \"show_all_polygons\": \"show_all_shapes\",\n        \"hide_all_polygons\": \"hide_all_shapes\",\n        \"toggle_all_polygons\": \"toggle_all_shapes\",\n    }\n    shortcuts = config_from_yaml.get(\"shortcuts\", {})\n    for old_key, new_key in _POLYGON_TO_SHAPE_RENAMES.items():\n        if old_key in shortcuts and new_key not in shortcuts:\n            logger.info(\n                \"Migrating old config: shortcuts.{} -> shortcuts.{}\",\n                old_key,\n                new_key,\n            )\n            shortcuts[new_key] = shortcuts.pop(old_key)\n\n\ndef get_user_config_file(create_if_missing: bool = True) -> str:\n    user_config_file: str = osp.join(osp.expanduser(\"~\"), \".labelmerc\")\n    if not osp.exists(user_config_file) and create_if_missing:\n        try:\n            with open(user_config_file, \"w\") as f:\n                f.write(\n                    \"# Labelme config file.\\n\"\n                    \"# Only add settings you want to override.\\n\"\n                    \"# For all available options and defaults, see:\\n\"\n                    \"#   https://github.com/wkentaro/labelme/blob/main/labelme/config/default_config.yaml\\n\"\n                    \"#\\n\"\n                    \"# Example:\\n\"\n                    \"# with_image_data: true\\n\"\n                    \"# auto_save: false\\n\"\n                    \"# labels: [cat, dog]\\n\"\n                )\n        except Exception:\n            logger.warning(\"Failed to save config: {!r}\", user_config_file)\n    return user_config_file\n\n\ndef load_config(config_file: Path | None, config_overrides: dict) -> dict:\n    config: dict\n    with open(osp.join(here, \"default_config.yaml\")) as f:\n        config = yaml.safe_load(f)\n\n    if config_file is not None:\n        with open(config_file) as f:\n            config_from_yaml = yaml.safe_load(f)\n        if isinstance(config_from_yaml, dict):\n            _migrate_config_from_file(config_from_yaml=config_from_yaml)\n            _update_dict(config, config_from_yaml, validate_item=_validate_config_item)\n\n    _update_dict(config, config_overrides, validate_item=_validate_config_item)\n\n    if not config[\"labels\"] and config[\"validate_label\"]:\n        raise ValueError(\"labels must be specified when validate_label is enabled\")\n\n    return config\n"
  },
  {
    "path": "labelme/config/default_config.yaml",
    "content": "auto_save: true\ndisplay_label_popup: true\nwith_image_data: false\nkeep_prev: false\nkeep_prev_scale: false\nkeep_prev_brightness_contrast: false\nlogger_level: info\n\nflags: null\nlabel_flags: null\nlabels: null\nfile_search: null\nsort_labels: true\nvalidate_label: null\n\ndefault_shape_color: [0, 255, 0]\nshape_color: auto  # null, 'auto', 'manual'\nshift_auto_shape_color: 0\nlabel_colors: null\n\nshape:\n  # drawing\n  line_color: [0, 255, 0, 128]\n  fill_color: [0, 0, 0, 64]\n  vertex_fill_color: [0, 255, 0, 255]\n  # selecting / hovering\n  select_line_color: [255, 255, 255, 255]\n  select_fill_color: [0, 255, 0, 64]\n  hvertex_fill_color: [255, 255, 255, 255]\n  point_size: 8\n\nai:\n  default: 'Sam2 (balanced)'\n\n# main\nflag_dock:\n  show: true\n  closable: true\n  movable: true\n  floatable: true\nlabel_dock:\n  show: true\n  closable: true\n  movable: true\n  floatable: true\nshape_dock:\n  show: true\n  closable: true\n  movable: true\n  floatable: true\nfile_dock:\n  show: true\n  closable: true\n  movable: true\n  floatable: true\n\n# label_dialog\nshow_label_text_field: true\nlabel_completion: startswith\nfit_to_content:\n  column: true\n  row: false\n\n# canvas\nepsilon: 10.0\ncanvas:\n  fill_drawing: true\n  # None: do nothing\n  # close: close polygon\n  double_click: close\n  # The max number of edits we can undo\n  num_backups: 10\n  # show crosshair\n  crosshair:\n    polygon: false\n    rectangle: true\n    circle: false\n    line: false\n    point: false\n    linestrip: false\n    ai_polygon: false\n    ai_mask: false\n\nshortcuts:\n  close: Ctrl+W\n  open: Ctrl+O\n  open_dir: Ctrl+U\n  quit: Ctrl+Q\n  save: Ctrl+S\n  save_as: Ctrl+Shift+S\n  save_to: null\n  delete_file: Ctrl+Delete\n\n  open_next: [D, Ctrl+Shift+D]\n  open_prev: [A, Ctrl+Shift+A]\n\n  zoom_in: [Ctrl++, Ctrl+=]\n  zoom_out: Ctrl+-\n  zoom_to_original: Ctrl+0\n  fit_window: Ctrl+F\n  fit_width: Ctrl+Shift+F\n\n  create_polygon: Ctrl+N\n  create_rectangle: Ctrl+R\n  create_circle: null\n  create_line: null\n  create_point: null\n  create_linestrip: null\n  edit_shape: Ctrl+J\n  delete_shape: Delete\n  duplicate_shape: Ctrl+D\n  copy_shape: Ctrl+C\n  paste_shape: Ctrl+V\n  undo: Ctrl+Z\n  undo_last_point: Ctrl+Z\n  edit_label: Ctrl+E\n  toggle_keep_prev_mode: Ctrl+P\n  remove_selected_point: [Meta+H, Backspace]\n\n  show_all_shapes: null\n  hide_all_shapes: null\n  toggle_all_shapes: T\n"
  },
  {
    "path": "labelme/shape.py",
    "content": "from __future__ import annotations\n\nimport copy\n\nimport numpy as np\nimport numpy.typing as npt\nimport skimage.measure\nfrom loguru import logger\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\n\nimport labelme.utils\n\n\nclass Shape:\n    # Handle point styles: square or round\n    P_SQUARE = 0\n    P_ROUND = 1\n\n    # Vertex interaction modes\n    MOVE_VERTEX = 0\n    NEAR_VERTEX = 1\n\n    # Width of the shape outline pen\n    PEN_WIDTH = 2\n\n    # The following class variables influence the drawing of all shape objects.\n    line_color: QtGui.QColor = QtGui.QColor(0, 255, 0, 128)\n    fill_color: QtGui.QColor = QtGui.QColor(0, 0, 0, 64)\n    vertex_fill_color: QtGui.QColor = QtGui.QColor(0, 255, 0, 255)\n    select_line_color: QtGui.QColor = QtGui.QColor(255, 255, 255, 255)\n    select_fill_color: QtGui.QColor = QtGui.QColor(0, 255, 0, 64)\n    hvertex_fill_color: QtGui.QColor = QtGui.QColor(255, 255, 255, 255)\n\n    # Default handle style, size, and zoom scale\n    point_type = P_ROUND\n    point_size = 8\n    scale = 1.0\n\n    _current_vertex_fill_color: QtGui.QColor\n\n    def __init__(\n        self,\n        label: str | None = None,\n        line_color: QtGui.QColor | None = None,\n        shape_type: str | None = None,\n        flags: dict[str, bool] | None = None,\n        group_id: int | None = None,\n        description: str | None = None,\n        mask: npt.NDArray[np.bool_] | None = None,\n    ):\n        self.label = label\n        self.group_id = group_id\n        self.points = []\n        self.point_labels = []\n        self.shape_type = shape_type\n        self._shape_raw = None\n        self._points_raw = []\n        self._shape_type_raw = None\n        self.fill = False\n        self.selected = False\n        self.flags = flags\n        self.description = description\n        self.other_data = {}\n        self.mask = mask\n\n        # Highlight state: which vertex is highlighted and how it looks\n        self._highlightIndex = None\n        self._highlightMode = self.NEAR_VERTEX\n        self._highlightSettings = {\n            self.NEAR_VERTEX: (4, self.P_ROUND),\n            self.MOVE_VERTEX: (1.5, self.P_SQUARE),\n        }\n\n        self._closed = False\n\n        if line_color is not None:\n            # Per-instance line color override (used for the pending line).\n            self.line_color = line_color\n\n    def _scale_point(self, point: QtCore.QPointF) -> QtCore.QPointF:\n        return QtCore.QPointF(point.x() * self.scale, point.y() * self.scale)\n\n    def setShapeRefined(self, shape_type, points, point_labels, mask=None):\n        self._shape_raw = (self.shape_type, self.points, self.point_labels)\n        self.shape_type = shape_type\n        self.points = points\n        self.point_labels = point_labels\n        self.mask = mask\n\n    def restoreShapeRaw(self):\n        if self._shape_raw is None:\n            return\n        self.shape_type, self.points, self.point_labels = self._shape_raw\n        self._shape_raw = None\n\n    @property\n    def shape_type(self):\n        return self._shape_type\n\n    @shape_type.setter\n    def shape_type(self, value):\n        if value is None:\n            value = \"polygon\"\n        if value not in [\n            \"polygon\",\n            \"rectangle\",\n            \"point\",\n            \"line\",\n            \"circle\",\n            \"linestrip\",\n            \"points\",\n            \"mask\",\n        ]:\n            raise ValueError(f\"Unexpected shape_type: {value}\")\n        self._shape_type = value\n\n    def close(self):\n        self._closed = True\n\n    def addPoint(self, point, label=1):\n        if self.points and point == self.points[0]:\n            self.close()\n        else:\n            self.points.append(point)\n            self.point_labels.append(label)\n\n    def canAddPoint(self):\n        return self.shape_type in [\"polygon\", \"linestrip\"]\n\n    def popPoint(self):\n        if self.points:\n            if self.point_labels:\n                self.point_labels.pop()\n            return self.points.pop()\n        return None\n\n    def insertPoint(self, i, point, label=1):\n        self.points.insert(i, point)\n        self.point_labels.insert(i, label)\n\n    def canRemovePoint(self) -> bool:\n        if not self.canAddPoint():\n            return False\n\n        if self.shape_type == \"polygon\" and len(self.points) <= 3:\n            return False\n\n        if self.shape_type == \"linestrip\" and len(self.points) <= 2:\n            return False\n\n        return True\n\n    def removePoint(self, i: int):\n        if not self.canRemovePoint():\n            logger.warning(\n                \"Cannot remove point from: shape_type=%r, len(points)=%d\",\n                self.shape_type,\n                len(self.points),\n            )\n            return\n\n        self.points.pop(i)\n        self.point_labels.pop(i)\n\n    def isClosed(self):\n        return self._closed\n\n    def setOpen(self):\n        self._closed = False\n\n    def paint(self, painter):\n        if self.mask is None and not self.points:\n            return\n\n        color = self.select_line_color if self.selected else self.line_color\n        pen = QtGui.QPen(color)\n        # Try using integer sizes for smoother drawing(?)\n        pen.setWidth(self.PEN_WIDTH)\n        painter.setPen(pen)\n\n        if self.shape_type == \"mask\" and self.mask is not None:\n            image_to_draw = np.zeros(self.mask.shape + (4,), dtype=np.uint8)\n            fill_color = (\n                self.select_fill_color.getRgb()\n                if self.selected\n                else self.fill_color.getRgb()\n            )\n            image_to_draw[self.mask] = fill_color\n            qimage = QtGui.QImage.fromData(labelme.utils.img_arr_to_data(image_to_draw))\n            qimage = qimage.scaled(\n                qimage.size() * self.scale,\n                QtCore.Qt.IgnoreAspectRatio,\n                QtCore.Qt.SmoothTransformation,\n            )\n\n            painter.drawImage(self._scale_point(point=self.points[0]), qimage)\n\n            line_path = QtGui.QPainterPath()\n            contours = skimage.measure.find_contours(np.pad(self.mask, pad_width=1))\n            for contour in contours:\n                contour += [self.points[0].y(), self.points[0].x()]\n                line_path.moveTo(\n                    self._scale_point(QtCore.QPointF(contour[0, 1], contour[0, 0]))\n                )\n                for point in contour[1:]:\n                    line_path.lineTo(\n                        self._scale_point(QtCore.QPointF(point[1], point[0]))\n                    )\n            painter.drawPath(line_path)\n\n        if self.points:\n            line_path = QtGui.QPainterPath()\n            vrtx_path = QtGui.QPainterPath()\n            negative_vrtx_path = QtGui.QPainterPath()\n\n            if self.shape_type in [\"rectangle\", \"mask\"]:\n                assert len(self.points) in [1, 2]\n                if len(self.points) == 2:\n                    rectangle = QtCore.QRectF(\n                        self._scale_point(self.points[0]),\n                        self._scale_point(self.points[1]),\n                    )\n                    line_path.addRect(rectangle)\n                if self.shape_type == \"rectangle\":\n                    for i in range(len(self.points)):\n                        self.drawVertex(vrtx_path, i)\n            elif self.shape_type == \"circle\":\n                assert len(self.points) in [1, 2]\n                if len(self.points) == 2:\n                    radius = labelme.utils.distance(\n                        self._scale_point(self.points[0] - self.points[1])\n                    )\n                    line_path.addEllipse(\n                        self._scale_point(self.points[0]), radius, radius\n                    )\n                for i in range(len(self.points)):\n                    self.drawVertex(vrtx_path, i)\n            elif self.shape_type == \"linestrip\":\n                line_path.moveTo(self._scale_point(self.points[0]))\n                for i, p in enumerate(self.points):\n                    line_path.lineTo(self._scale_point(p))\n                    self.drawVertex(vrtx_path, i)\n            elif self.shape_type == \"points\":\n                assert len(self.points) == len(self.point_labels)\n                for i, point_label in enumerate(self.point_labels):\n                    if point_label == 1:\n                        self.drawVertex(vrtx_path, i)\n                    else:\n                        self.drawVertex(negative_vrtx_path, i)\n            else:\n                line_path.moveTo(self._scale_point(self.points[0]))\n                # Uncommenting the following line will draw 2 paths\n                # for the 1st vertex, and make it non-filled, which\n                # may be desirable.\n                # self.drawVertex(vrtx_path, 0)\n\n                for i, p in enumerate(self.points):\n                    line_path.lineTo(self._scale_point(p))\n                    self.drawVertex(vrtx_path, i)\n                if self.isClosed():\n                    line_path.lineTo(self._scale_point(self.points[0]))\n\n            painter.drawPath(line_path)\n            if vrtx_path.length() > 0:\n                painter.drawPath(vrtx_path)\n                painter.fillPath(vrtx_path, self._current_vertex_fill_color)\n            if self.fill and self.shape_type not in [\n                \"line\",\n                \"linestrip\",\n                \"points\",\n                \"mask\",\n            ]:\n                color = self.select_fill_color if self.selected else self.fill_color\n                painter.fillPath(line_path, color)\n\n            pen.setColor(QtGui.QColor(255, 0, 0, 255))\n            painter.setPen(pen)\n            painter.drawPath(negative_vrtx_path)\n            painter.fillPath(negative_vrtx_path, QtGui.QColor(255, 0, 0, 255))\n\n    def drawVertex(self, path, i):\n        d = self.point_size\n        shape = self.point_type\n        point = self._scale_point(self.points[i])\n        if i == self._highlightIndex:\n            size, shape = self._highlightSettings[self._highlightMode]\n            d *= size  # type: ignore[assignment]\n        if self._highlightIndex is not None:\n            self._current_vertex_fill_color = self.hvertex_fill_color\n        else:\n            self._current_vertex_fill_color = self.vertex_fill_color\n        if shape == self.P_SQUARE:\n            path.addRect(point.x() - d / 2, point.y() - d / 2, d, d)\n        elif shape == self.P_ROUND:\n            path.addEllipse(point, d / 2.0, d / 2.0)\n        else:\n            assert False, \"unsupported vertex shape\"\n\n    def nearestVertex(self, point: QtCore.QPointF, epsilon: float) -> int | None:\n        min_distance = float(\"inf\")\n        min_i = None\n        point = self._scale_point(point)\n        for i, p in enumerate(self.points):\n            p = self._scale_point(p)\n            dist = labelme.utils.distance(p - point)\n            if dist <= epsilon and dist < min_distance:\n                min_distance = dist\n                min_i = i\n        return min_i\n\n    def nearestEdge(self, point: QtCore.QPointF, epsilon: float) -> int | None:\n        min_distance = float(\"inf\")\n        post_i = None\n        point = self._scale_point(point)\n        for i in range(len(self.points)):\n            start = self._scale_point(self.points[i - 1])\n            end = self._scale_point(self.points[i])\n            line = [start, end]\n            dist = labelme.utils.distancetoline(point, line)\n            if dist <= epsilon and dist < min_distance:\n                min_distance = dist\n                post_i = i\n        return post_i\n\n    def containsPoint(self, point: QtCore.QPointF) -> bool:\n        if self.shape_type in [\"line\", \"linestrip\", \"points\"]:\n            return False\n        if self.shape_type == \"point\":\n            if not self.points:\n                return False\n            return labelme.utils.distance(point - self.points[0]) <= self.point_size / 2\n        if self.mask is not None:\n            raw_y = int(round(point.y() - self.points[0].y()))\n            raw_x = int(round(point.x() - self.points[0].x()))\n            if (\n                raw_y < 0\n                or raw_y >= self.mask.shape[0]\n                or raw_x < 0\n                or raw_x >= self.mask.shape[1]\n            ):\n                return False\n            return bool(self.mask[raw_y, raw_x])\n        return self.makePath().contains(point)\n\n    def makePath(self):\n        if self.shape_type in [\"rectangle\", \"mask\"]:\n            path = QtGui.QPainterPath()\n            if len(self.points) == 2:\n                path.addRect(QtCore.QRectF(self.points[0], self.points[1]))\n        elif self.shape_type == \"circle\":\n            path = QtGui.QPainterPath()\n            if len(self.points) == 2:\n                raidus = labelme.utils.distance(self.points[0] - self.points[1])\n                path.addEllipse(self.points[0], raidus, raidus)\n        else:\n            path = QtGui.QPainterPath(self.points[0])\n            for p in self.points[1:]:\n                path.lineTo(p)\n        return path\n\n    def boundingRect(self):\n        return self.makePath().boundingRect()\n\n    def moveBy(self, offset):\n        self.points = [p + offset for p in self.points]\n\n    def moveVertex(self, i: int, pos: QtCore.QPointF) -> None:\n        self.points[i] = pos\n\n    def highlightVertex(self, i: int, action: int) -> None:\n        self._highlightIndex = i\n        self._highlightMode = action\n\n    def highlightClear(self) -> None:\n        self._highlightIndex = None\n\n    def copy(self):\n        return copy.deepcopy(self)\n\n    def __len__(self):\n        return len(self.points)\n\n    def __getitem__(self, key):\n        return self.points[key]\n\n    def __setitem__(self, key, value):\n        self.points[key] = value\n"
  },
  {
    "path": "labelme/testing.py",
    "content": "import json\nimport os.path as osp\n\nimport imgviz\n\nimport labelme.utils\n\n\ndef assert_labelfile_sanity(filename):\n    assert osp.exists(filename)\n\n    data = json.load(open(filename))\n\n    assert \"imagePath\" in data\n    imageData = data.get(\"imageData\", None)\n    if imageData is None:\n        parent_dir = osp.dirname(filename)\n        img_file = osp.join(parent_dir, data[\"imagePath\"])\n        assert osp.exists(img_file)\n        img = imgviz.io.imread(img_file)\n    else:\n        img = labelme.utils.img_b64_to_arr(imageData)\n\n    H, W = img.shape[:2]\n    assert H == data[\"imageHeight\"]\n    assert W == data[\"imageWidth\"]\n\n    assert \"shapes\" in data\n    for shape in data[\"shapes\"]:\n        assert \"label\" in shape\n        assert \"points\" in shape\n        for x, y in shape[\"points\"]:\n            assert 0 <= x <= W\n            assert 0 <= y <= H\n"
  },
  {
    "path": "labelme/translate/de_DE.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"de_DE\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>KI-gestützte Annotation</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>KI schlägt Annotation in den Modi 'AI-Polygon' und 'AI-Mask' vor</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Wählen Sie den Modus 'AI-Polygon' oder 'AI-Mask', um AI-Assisted Annotation zu aktivieren</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>KI-Prompt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>z.B. Hund,Katze,Vogel</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Ausführen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Score</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>KI erstellt Annotationen aus dem Textprompt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Wählen Sie den Modus 'Polygon', 'Rechteck', 'AI-Polygon' oder 'AI-Maske' zum Aktivieren</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>%r wird erstellt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC zum Abbrechen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter oder Leertaste zum Abschließen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Formen bearbeiten</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Punkte anklicken zum Einbeziehen oder Shift+Klick zum Ausschließen (KI-Polygon)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Punkte anklicken zum Einbeziehen oder Shift+Klick zum Ausschließen (KI-Maske)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Startpunkt der Linie anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Endpunkt der Linie anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Startpunkt der Linienfolge anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Nächsten Punkt anklicken oder mit Ctrl/Cmd+Klick abschließen (Linienfolge)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Mittelpunkt des Kreises anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Punkt auf dem Kreisumfang anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Erste Ecke des Rechtecks anklicken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Klicken zum Hinzufügen eines Punktes</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Klicken und ziehen zum Verschieben des Punktes</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Klick zum Löschen des Punktes</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Klick zum Erstellen eines Punktes auf der Form</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Klicken und ziehen zum Verschieben der Form</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Rechtsklick und Ziehen, um die Form zu kopieren</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Gegenüberliegende Ecke des Rechtecks anklicken (Shift für Quadrat)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Markierungen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Annotationsliste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Label auswählen, um mit der Annotation zu beginnen. Mit 'Esc' abwählen.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Label-Liste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Dateiname suchen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Dateiliste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Beenden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Anwendung beenden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Öffnen\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Bild- oder Label-Datei öffnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Verzeichnis öffnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>&amp;Nächstes Bild</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Nächstes öffnen (Strg+Umschalt gedrückt halten, um Labels zu kopieren)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>&amp;Vorheriges Bild</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Vorheriges öffnen (Strg+Umschalt gedrückt halten, um Labels zu kopieren)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Speichern\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Labels in Datei speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Speichern &amp;unter</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Labels in anderer Datei speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Datei löschen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Aktuelle Label-Datei löschen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>&amp;Ausgabeverzeichnis ändern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Ändern, wo Annotationen geladen/gespeichert werden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>&amp;Automatisch speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Automatisch speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Mit Bilddaten speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Bilddaten in Label-Datei speichern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Schließen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Aktuelle Datei schließen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Vorherige Annotation beibehalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>&quot;Vorherige Annotation beibehalten&quot; Modus umschalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Polygone erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Mit dem Zeichnen von Polygonen beginnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Rechteck erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Mit dem Zeichnen von Rechtecken beginnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Kreis erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Mit dem Zeichnen von Kreisen beginnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Linie erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Mit dem Zeichnen von Linien beginnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Punkt erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Mit dem Zeichnen von Punkten beginnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Linienfolge erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Mit dem Zeichnen einer Linienfolge beginnen. Strg+Linksklick beendet die Erstellung.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>KI-Polygon erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Mit dem Zeichnen eines KI-Polygons beginnen. Strg+Linksklick beendet die Erstellung.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>KI-Maske erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Mit dem Zeichnen einer KI-Maske beginnen. Strg+Linksklick beendet die Erstellung.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Formen bearbeiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Ausgewählte Formen verschieben und bearbeiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Formen löschen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Ausgewählte Formen löschen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Formen duplizieren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Duplikat der ausgewählten Formen erstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Formen kopieren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Ausgewählte Formen in Zwischenablage kopieren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Formen einfügen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Kopierte Formen einfügen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Letzten Punkt rückgängig machen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Letzten gezeichneten Punkt rückgängig machen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Ausgewählten Punkt entfernen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Ausgewählten Punkt aus Polygon entfernen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Rückgängig\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Letztes Hinzufügen und Bearbeiten der Form rückgängig machen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>&amp;Verbergen\nFormen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Alle Formen verbergen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>&amp;Anzeigen\nFormen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Alle Formen anzeigen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>&amp;Umschalten\nFormen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Alle Formen umschalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Tutorial-Seite anzeigen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Bild vergrößern oder verkleinern. Auch mit {} und {} von der Leinwand aus zugänglich.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Strg+Mausrad</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Vergrößern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Zoomstufe erhöhen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Verkleinern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Zoomstufe verringern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>&amp;Originalgröße</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Auf Originalgröße zoomen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>&amp;Vorherige Skalierung beibehalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Vorherige Zoomskalierung beibehalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>&amp;An Fenster anpassen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Zoom folgt der Fenstergröße</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>&amp;An Breite anpassen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Zoom folgt der Fensterbreite</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>&amp;Helligkeit/Kontrast</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Helligkeit und Kontrast einstellen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Label bearbeiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Label der ausgewählten Form ändern</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Gezeichnetes Polygon füllen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Polygon beim Zeichnen füllen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Vorherige Helligkeit/Kontrast beibehalten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Datei</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Bearbeiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Ansicht</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Hilfe</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>&amp;Zuletzt geöffnet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s gestartet.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Ungültiges Label</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Ungültiges Label '{}' mit Validierungstyp '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Fehler beim Speichern der Labeldaten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Fehler beim Öffnen der Datei</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Datei nicht gefunden: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>%s wird geladen...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Fehler beim Lesen von %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Stellen Sie sicher, dass &lt;i&gt;{0}&lt;/i&gt; eine gültige Bilddatei ist.&lt;br/&gt;Unterstützte Bildformate: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s geladen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Bild- und Label-Dateien (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Bild- oder Label-Datei auswählen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Annotationen im Verzeichnis speichern/laden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Annotationen werden in %s gespeichert/geladen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Datei auswählen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Label-Dateien (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Datei auswählen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Möchten Sie diese Label-Datei endgültig löschen?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Achtung</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Annotationen in &quot;{}&quot; speichern vor dem Schließen?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Annotationen speichern?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Möchten Sie {} Formen endgültig löschen?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Verzeichnis öffnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Einstellungen…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Konfigurationsdatei im Texteditor öffnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Keine Konfigurationsdatei</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>Die Konfiguration wurde als YAML-Ausdruck über die Kommandozeile bereitgestellt.\n\nUm den Einstellungseditor zu verwenden, starten Sie Labelme mit einer Konfigurationsdatei:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Konfigurationsfehler</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Beim Laden der Konfiguration wurden Fehler gefunden. Bitte überprüfen Sie die folgenden Fehler und laden Sie Ihre Konfiguration neu oder ignorieren Sie die fehlerhaften Zeilen.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Stellen Sie sicher, dass &lt;i&gt;%s&lt;/i&gt; eine gültige Beschriftungsdatei ist.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Stellen Sie sicher, dass &lt;i&gt;%s&lt;/i&gt; eine gültige Bilddatei ist.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Layout zurücksetzen</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/es_ES.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"es_ES\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Anotación asistida por IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>La IA sugiere anotación en los modos 'AI-Polygon' y 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Seleccione el modo 'AI-Polygon' o 'AI-Mask' para habilitar AI-Assisted Annotation</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>Indicación IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>p. ej., perro, gato, pájaro</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Ejecutar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Puntuación</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>La IA crea anotaciones a partir del texto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Seleccione el modo 'Polygon', 'Rectangle', 'AI-Polygon' o 'AI-Mask' para habilitar</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Haz clic y arrastra para mover el punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Haz clic y arrastra para mover la forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Creando %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC para cancelar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter o Espacio para finalizar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Editando formas</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Haz clic en los puntos para incluir o Mayús+Clic para excluir (polígono IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Haz clic en los puntos para incluir o Mayús+Clic para excluir (máscara IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Haz clic en el punto inicial de la línea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Haz clic en el punto final de la línea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Haz clic en el punto inicial de la línea continua</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Haz clic en el siguiente punto o Ctrl/Cmd+Clic para finalizar (línea continua)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Haz clic en el punto central del círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Haz clic en un punto de la circunferencia del círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Haz clic en la primera esquina del rectángulo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Haz clic para añadir un punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + MAYÚS + Clic para eliminar el punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Clic para crear un punto en la forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Clic derecho y arrastra para copiar la forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Haz clic en la esquina opuesta del rectángulo (Shift para cuadrado)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Marcadores</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Lista de anotaciones</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Selecciona una etiqueta para comenzar a anotar. Presiona 'Esc' para deseleccionar.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Lista de etiquetas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Buscar nombre de archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Lista de archivos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Salir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Salir de la aplicación</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Abrir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Abrir archivo de imagen o etiqueta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Abrir directorio</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Imagen &amp;siguiente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Abrir siguiente (mantén Ctrl+Mayús para copiar etiquetas)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Imagen &amp;anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Abrir anterior (mantén Ctrl+Mayús para copiar etiquetas)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Guardar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Guardar etiquetas en archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Guardar &amp;como</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Guardar etiquetas en un archivo diferente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Eliminar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Eliminar archivo de etiqueta actual</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>Cambiar directorio de &amp;salida</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Cambiar dónde se cargan/guardan las anotaciones</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Guardar &amp;automáticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Guardar automáticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Guardar con datos de imagen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Guardar datos de imagen en el archivo de etiqueta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Cerrar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Cerrar archivo actual</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Mantener anotación anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Crear polígonos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Empezar a dibujar polígonos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Crear rectángulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Empezar a dibujar rectángulos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Crear círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Empezar a dibujar círculos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Crear línea</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Empezar a dibujar líneas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Crear punto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Empezar a dibujar puntos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Crear línea continua</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Empezar a dibujar línea continua. Ctrl+Clic izquierdo finaliza la creación.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Crear polígono IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Empezar a dibujar polígono IA. Ctrl+Clic izquierdo finaliza la creación.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Crear máscara IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Empezar a dibujar máscara IA. Ctrl+Clic izquierdo finaliza la creación.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Editar formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Mover y editar las formas seleccionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Eliminar formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Eliminar las formas seleccionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Duplicar formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Crear un duplicado de las formas seleccionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Copiar formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Copiar formas seleccionadas al portapapeles</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Pegar formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Pegar formas copiadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Deshacer último punto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Deshacer último punto dibujado</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Eliminar punto seleccionado</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Eliminar punto seleccionado del polígono</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Deshacer</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Deshacer última adición y edición de forma</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Ocultar &amp;formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Ocultar todas las formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Mostrar &amp;formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Mostrar todas las formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Alternar &amp;formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Alternar todas las formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Mostrar página del tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Acercar o alejar la imagen. También accesible con {} y {} desde el lienzo.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Rueda</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Acercar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Aumentar nivel de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Alejar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Disminuir nivel de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Tamaño &amp;original</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Zoom al tamaño original</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Mantener escala &amp;anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Mantener escala de zoom anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>Ajustar a &amp;ventana</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>El zoom sigue el tamaño de la ventana</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Ajustar a &amp;ancho</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>El zoom sigue el ancho de la ventana</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>Brillo y &amp;contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Ajustar brillo y contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Editar etiqueta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Modificar la etiqueta de la forma seleccionada</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Rellenar polígono al dibujar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Rellenar polígono mientras se dibuja</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Editar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Ver</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Ayuda</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Abrir &amp;recientes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s iniciado.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Etiqueta no válida</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Etiqueta no válida '{}' con tipo de validación '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Error al guardar datos de etiqueta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Error al abrir archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>No existe el archivo: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Cargando %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Error al leer %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Asegúrate de que &lt;i&gt;{0}&lt;/i&gt; sea un archivo de imagen válido.&lt;br/&gt;Formatos de imagen admitidos: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>Cargado %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Archivos de imagen y etiqueta (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Elegir archivo de imagen o etiqueta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Guardar/Cargar anotaciones en directorio</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Las anotaciones se guardarán/cargarán en %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Elegir archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Archivos de etiqueta (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Elegir archivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Estás a punto de eliminar permanentemente este archivo de etiqueta, ¿continuar de todos modos?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Atención</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>¿Guardar anotaciones en &quot;{}&quot; antes de cerrar?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>¿Guardar anotaciones?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Estás a punto de eliminar permanentemente {} formas, ¿continuar de todos modos?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Abrir directorio</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Alternar modo &quot;mantener anotación anterior&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Mantener brillo/contraste anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Preferencias…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Abrir archivo de configuración en editor de texto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Sin archivo de configuración</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>La configuración se proporcionó como una expresión YAML a través de la línea de comandos.\n\nPara usar el editor de preferencias, inicie Labelme con un archivo de configuración:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Errores de Configuración</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Se encontraron errores al cargar la configuración. Por favor, revise los errores a continuación y recargue su configuración o ignore las líneas erróneas.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Asegúrate de que &lt;i&gt;%s&lt;/i&gt; sea un archivo de etiqueta válido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Asegúrate de que &lt;i&gt;%s&lt;/i&gt; sea un archivo de imagen válido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Restablecer diseño</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/fa_IR.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"fa_IR\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>حاشیه‌نویسی با کمک هوش مصنوعی</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>هوش مصنوعی حاشیه‌نویسی را در حالت‌های 'AI-Polygon' و 'AI-Mask' پیشنهاد می‌دهد</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>برای فعال کردن AI-Assisted Annotation، حالت «AI-Polygon» یا «AI-Mask» را انتخاب کنید</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>پیشنهاد هوش مصنوعی</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>مثال: سگ، گربه، پرنده</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>اجرا</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>امتیاز</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>هوش مصنوعی حاشیه‌نویسی‌ها را از متن ایجاد می‌کند</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>برای فعال کردن، حالت «Polygon»، «Rectangle»، «AI-Polygon» یا «AI-Mask» را انتخاب کنید</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>کلیک و کشیدن برای جابجایی نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>کلیک و کشیدن برای جابجایی شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>در حال ایجاد %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC برای لغو</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter یا Space برای نهایی کردن</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>ویرایش اشکال</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>کلیک برای شامل کردن نقاط یا Shift+کلیک برای حذف (چندضلعی هوش مصنوعی)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>کلیک برای شامل کردن نقاط یا Shift+کلیک برای حذف (ماسک هوش مصنوعی)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>کلیک روی نقطه شروع خط</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>کلیک روی نقطه پایان خط</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>کلیک روی نقطه شروع خط چندتکه‌ای</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>کلیک روی نقطه بعدی یا Ctrl/Cmd+کلیک برای پایان خط چندتکه‌ای</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>کلیک روی نقطه مرکز دایره</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>کلیک روی نقطه روی محیط دایره</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>کلیک روی گوشه اول مستطیل</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>کلیک برای افزودن نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + کلیک برای حذف نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + کلیک برای ایجاد نقطه روی شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>کلیک راست و کشیدن برای کپی شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>کلیک روی گوشه مقابل مستطیل (Shift برای مربع)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>پرچم‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>فهرست حاشیه‌نویسی‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>برچسب را انتخاب کنید تا شروع به حاشیه‌نویسی کنید. 'Esc' را فشار دهید تا انتخاب لغو شود.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>فهرست برچسب‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>جستجوی نام فایل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>فهرست فایل‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>خروج(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>خروج از برنامه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>باز کردن(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>باز کردن فایل تصویر یا برچسب</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>باز کردن پوشه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>تصویر بعدی(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>باز کردن بعدی (Ctrl+Shift را نگه دارید تا برچسب‌ها کپی شوند)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>تصویر قبلی(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>باز کردن قبلی (Ctrl+Shift را نگه دارید تا برچسب‌ها کپی شوند)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>ذخیره(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>ذخیره برچسب‌ها در فایل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>ذخیره با نام دیگر(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>ذخیره برچسب‌ها در فایل دیگر</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>حذف(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>حذف فایل برچسب فعلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>تغییر مسیر خروجی(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>تغییر محل بارگذاری/ذخیره حاشیه‌نویسی‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>ذخیره خودکار(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>ذخیره خودکار</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>ذخیره با داده تصویر</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>ذخیره داده تصویر در فایل برچسب</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>بستن(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>بستن فایل فعلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>نگه داشتن حاشیه‌نویسی قبلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>ایجاد چندضلعی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>شروع رسم چندضلعی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>ایجاد مستطیل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>شروع رسم مستطیل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>ایجاد دایره</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>شروع رسم دایره</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>ایجاد خط</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>شروع رسم خط</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>ایجاد نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>شروع رسم نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>ایجاد خط چندتکه‌ای</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>شروع رسم خط چندتکه‌ای. Ctrl+کلیک چپ برای پایان.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>ایجاد چندضلعی هوش مصنوعی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>شروع رسم چندضلعی هوش مصنوعی. Ctrl+کلیک چپ برای پایان.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>ایجاد ماسک هوش مصنوعی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>شروع رسم ماسک هوش مصنوعی. Ctrl+کلیک چپ برای پایان.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>ویرایش شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>جابجایی و ویرایش شکل‌های انتخاب شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>حذف شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>حذف شکل‌های انتخاب شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>تکثیر شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>ایجاد کپی از شکل‌های انتخاب شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>کپی شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>کپی شکل‌های انتخاب شده به کلیپ‌بورد</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>چسباندن شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>چسباندن شکل‌های کپی شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>بازگشت آخرین نقطه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>بازگشت آخرین نقطه رسم شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>حذف نقطه انتخاب شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>حذف نقطه انتخاب شده از چندضلعی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>بازگشت</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>بازگشت آخرین افزودن و ویرایش شکل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>مخفی کردن شکل(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>مخفی کردن همه شکل‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>نمایش شکل(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>نمایش همه شکل‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>تغییر وضعیت شکل(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>تغییر وضعیت همه شکل‌ها</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>آموزش(&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>نمایش صفحه آموزش</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>زوم</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>زوم کردن تصویر. همچنین از طریق {} و {} در بوم قابل دسترسی است.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+چرخ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>بزرگ‌نمایی(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>افزایش سطح زوم</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>کوچک‌نمایی(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>کاهش سطح زوم</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>اندازه اصلی(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>زوم به اندازه اصلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>نگه داشتن مقیاس قبلی(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>نگه داشتن مقیاس زوم قبلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>تناسب با پنجره(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>زوم متناسب با اندازه پنجره</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>تناسب با عرض(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>زوم متناسب با عرض پنجره</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>روشنایی و کنتراست(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>تنظیم روشنایی و کنتراست</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>ویرایش برچسب(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>تغییر برچسب شکل انتخاب شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>پر کردن چندضلعی رسم شده</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>پر کردن چندضلعی هنگام رسم</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>فایل(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>ویرایش(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>نمایش(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>راهنما(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>باز کردن اخیر(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s راه‌اندازی شد.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>برچسب نامعتبر</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>برچسب نامعتبر '{}' با نوع اعتبارسنجی '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>خطا در ذخیره داده برچسب</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>خطا در باز کردن فایل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>چنین فایلی وجود ندارد: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>در حال بارگذاری %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>خطا در خواندن %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;مطمئن شوید &lt;i&gt;{0}&lt;/i&gt; یک فایل تصویر معتبر است.&lt;br/&gt;فرمت‌های تصویر پشتیبانی شده: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>بارگذاری شد %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>فایل‌های تصویر و برچسب (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - انتخاب فایل تصویر یا برچسب</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - ذخیره/بارگذاری حاشیه‌نویسی‌ها در پوشه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . حاشیه‌نویسی‌ها در %s ذخیره/بارگذاری خواهند شد</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - انتخاب فایل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>فایل‌های برچسب (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>انتخاب فایل</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>شما در حال حذف دائمی این فایل برچسب هستید، ادامه دهید؟</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>توجه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>قبل از بستن، حاشیه‌نویسی‌ها را در &quot;{}&quot; ذخیره کنید؟</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>ذخیره حاشیه‌نویسی‌ها؟</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>شما در حال حذف دائمی {} شکل هستید، ادامه دهید؟</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - باز کردن پوشه</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>تغییر وضعیت حالت &quot;نگه داشتن حاشیه‌نویسی قبلی&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>نگه داشتن روشنایی/کنتراست قبلی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>تنظیمات…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>باز کردن فایل پیکربندی در ویرایشگر متن</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>فایل پیکربندی وجود ندارد</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>پیکربندی به صورت عبارت YAML از طریق خط فرمان ارائه شده است.\n\nبرای استفاده از ویرایشگر تنظیمات، Labelme را با یک فایل پیکربندی اجرا کنید:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>خطاهای پیکربندی</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>هنگام بارگیری پیکربندی خطاهایی یافت شد. لطفاً خطاهای زیر را بررسی کنید و پیکربندی خود را مجدداً بارگیری کنید یا خطوط نادرست را نادیده بگیرید.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;مطمئن شوید &lt;i&gt;%s&lt;/i&gt; یک فایل برچسب معتبر است.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;مطمئن شوید &lt;i&gt;%s&lt;/i&gt; یک فایل تصویر معتبر است.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>بازنشانی چیدمان</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/fr_FR.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"fr_FR\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Annotation assistée par IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>L'IA suggère l'annotation dans les modes 'AI-Polygon' et 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Sélectionnez le mode 'AI-Polygon' ou 'AI-Mask' pour activer AI-Assisted Annotation</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>Invite IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>ex. : chien,chat,oiseau</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Exécuter</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Score</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>L'IA crée des annotations à partir du texte</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Sélectionnez le mode 'Polygon', 'Rectangle', 'AI-Polygon' ou 'AI-Mask' pour activer</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Cliquer et glisser pour déplacer le point</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Cliquer et glisser pour déplacer la forme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Création de %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC pour annuler</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Entrée ou Espace pour finaliser</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Modification des formes</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Cliquer sur les points à inclure ou Maj+Cliquer pour exclure (polygone IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Cliquer sur les points à inclure ou Maj+Cliquer pour exclure (masque IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Cliquer sur le point de départ de la ligne</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Cliquer sur le point d'arrivée de la ligne</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Cliquer sur le point de départ de la polyligne</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Cliquer sur le point suivant ou Ctrl/Cmd+Cliquer pour terminer la polyligne</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Cliquer sur le point central du cercle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Cliquer sur un point de la circonférence du cercle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Cliquer sur le premier coin du rectangle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Cliquer pour ajouter un point</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + MAJ + Cliquer pour supprimer le point</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Cliquer pour créer un point sur la forme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Clic droit et glisser pour copier la forme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Cliquer sur le coin opposé du rectangle (Shift pour carré)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Drapeaux</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Liste des annotations</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Sélectionner une étiquette pour commencer l'annotation. Appuyer sur 'Esc' pour désélectionner.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Liste des étiquettes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Rechercher un nom de fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Liste des fichiers</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Quitter</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Quitter l'application</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Ouvrir\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Ouvrir une image ou un fichier d'étiquettes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Ouvrir le répertoire</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Image &amp;suivante</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Ouvrir la suivante (maintenir Ctrl+Maj pour copier les étiquettes)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Image &amp;précédente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Ouvrir la précédente (maintenir Ctrl+Maj pour copier les étiquettes)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Enregistrer\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Enregistrer les étiquettes dans un fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Enregistrer &amp;sous</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Enregistrer les étiquettes dans un autre fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Supprimer le fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Supprimer le fichier d'étiquettes actuel</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>&amp;Changer le répertoire de sortie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Changer où les annotations sont chargées/enregistrées</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Enregistrer &amp;automatiquement</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Enregistrer automatiquement</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Enregistrer avec les données d'image</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Enregistrer les données d'image dans le fichier d'étiquettes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Fermer</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Fermer le fichier actuel</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Conserver l'annotation précédente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Créer des polygones</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Commencer à dessiner des polygones</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Créer un rectangle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Commencer à dessiner des rectangles</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Créer un cercle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Commencer à dessiner des cercles</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Créer une ligne</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Commencer à dessiner des lignes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Créer un point</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Commencer à dessiner des points</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Créer une polyligne</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Commencer à dessiner une polyligne. Ctrl+Clic gauche termine la création.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Créer un polygone IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Commencer à dessiner un polygone IA. Ctrl+Clic gauche termine la création.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Créer un masque IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Commencer à dessiner un masque IA. Ctrl+Clic gauche termine la création.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Modifier les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Déplacer et modifier les formes sélectionnées</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Supprimer les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Supprimer les formes sélectionnées</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Dupliquer les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Créer un doublon des formes sélectionnées</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Copier les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Copier les formes sélectionnées dans le presse-papiers</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Coller les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Coller les formes copiées</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Annuler le dernier point</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Annuler le dernier point dessiné</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Supprimer le point sélectionné</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Supprimer le point sélectionné du polygone</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Annuler\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Annuler le dernier ajout et la dernière modification de forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>&amp;Masquer\nles formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Masquer toutes les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>&amp;Afficher\nles formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Afficher toutes les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>&amp;Basculer\nles formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Basculer toutes les formes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutoriel</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Afficher la page du tutoriel</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Zoomer ou dézoomer l'image. Également accessible avec {} et {} depuis le canevas.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Molette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>Zoom &amp;avant</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Augmenter le niveau de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>Zoom &amp;arrière</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Diminuer le niveau de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Taille &amp;d'origine</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Zoomer à la taille d'origine</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>&amp;Conserver l'échelle précédente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Conserver l'échelle de zoom précédente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>&amp;Adapter à la fenêtre</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Le zoom suit la taille de la fenêtre</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Adapter la &amp;largeur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Le zoom suit la largeur de la fenêtre</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>&amp;Luminosité et contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Ajuster la luminosité et le contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Modifier l'étiquette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Modifier l'étiquette de la forme sélectionnée</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Remplir le polygone en cours de dessin</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Remplir le polygone pendant le dessin</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Modifier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Affichage</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Aide</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Fichiers &amp;récents</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s démarré.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Étiquette invalide</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Étiquette invalide '{}' avec le type de validation '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Erreur lors de l'enregistrement des données d'étiquettes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Erreur lors de l'ouverture du fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Fichier introuvable : &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Chargement de %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Erreur lors de la lecture de %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Assurez-vous que &lt;i&gt;{0}&lt;/i&gt; est un fichier d'image valide.&lt;br/&gt;Formats d'image pris en charge : {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s chargé</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Fichiers Image &amp; Étiquettes (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Choisir un fichier Image ou Étiquette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Enregistrer/Charger les annotations dans le répertoire</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Les annotations seront enregistrées/chargées dans %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Choisir un fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Fichiers d'étiquettes (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Choisir un fichier</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Vous êtes sur le point de supprimer définitivement ce fichier d'étiquettes, continuer quand même ?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Attention</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Enregistrer les annotations dans &quot;{}&quot; avant de fermer ?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Enregistrer les annotations ?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Vous êtes sur le point de supprimer définitivement {} formes, continuer quand même ?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Ouvrir le répertoire</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Activer/désactiver le mode &quot;conserver l'annotation précédente&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Conserver les réglages de luminosité/contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Préférences…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Ouvrir le fichier de configuration dans l'éditeur de texte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Aucun fichier de configuration</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>La configuration a été fournie sous forme d'expression YAML via la ligne de commande.\n\nPour utiliser l'éditeur de préférences, démarrez Labelme avec un fichier de configuration :\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Erreurs de Configuration</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Des erreurs ont été trouvées lors du chargement de la configuration. Veuillez examiner les erreurs ci-dessous et recharger votre configuration ou ignorer les lignes erronées.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Assurez-vous que &lt;i&gt;%s&lt;/i&gt; est un fichier d'étiquettes valide.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Assurez-vous que &lt;i&gt;%s&lt;/i&gt; est un fichier image valide.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Réinitialiser la disposition</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/hu_HU.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"hu_HU\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>MI-támogatott annotáció</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>Az MI annotációt javasol az 'AI-Polygon' és 'AI-Mask' módokban</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Válassza az 'AI-Polygon' vagy 'AI-Mask' módot az AI-Assisted Annotation engedélyezéséhez</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI prompt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>pl. kutya,macska,madár</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Futtatás</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Pontszám</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>Az AI annotációkat hoz létre a szöveges promptból</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Válassza a 'Polygon', 'Rectangle', 'AI-Polygon' vagy 'AI-Mask' módot az engedélyezéshez</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>%r létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC a megszakításhoz</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter vagy Szóköz a befejezéshez</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Alakzatok szerkesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Kattintson a pontokra a belefoglaláshoz vagy Shift+Kattintás a kizáráshoz (AI sokszög)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Kattintson a pontokra a belefoglaláshoz vagy Shift+Kattintás a kizáráshoz (AI maszk)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Kattintson a vonal kezdőpontjára</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Kattintson a vonal végpontjára</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Kattintson a vonallánc kezdőpontjára</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Kattintson a következő pontra vagy Ctrl/Cmd+Kattintás a befejezéshez (vonallánc)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Kattintson a kör középpontjára</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Kattintson a kör kerületén lévő pontra</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Kattintson a téglalap első sarkára</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Kattintson pont hozzáadásához</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Kattintson és húzza a pont mozgatásához</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Kattintás a pont törléséhez</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Kattintás pont létrehozásához az alakzaton</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Kattintson és húzza az alakzat mozgatásához</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Jobb gombbal kattintás és húzás az alakzat másolásához</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Kattintson a téglalap ellentétes sarkára (Shift a négyzethez)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Jelzők</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Annotációlista</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Válasszon címkét az annotálás megkezdéséhez. Nyomja meg az 'Esc' gombot a kijelölés megszüntetéséhez.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Címkelista</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Fájlnév keresése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Fájllista</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Kilépés</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Alkalmazás bezárása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Megnyitás\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Kép vagy címke fájl megnyitása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Könyvtár megnyitása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>&amp;Következő kép</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Következő megnyitása (tartsa lenyomva a Ctrl+Shift-et a címkék másolásához)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>&amp;Előző kép</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Előző megnyitása (tartsa lenyomva a Ctrl+Shift-et a címkék másolásához)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Mentés\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Címkék mentése fájlba</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Mentés &amp;másként</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Címkék mentése másik fájlba</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Fájl törlése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Jelenlegi címke fájl törlése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>&amp;Kimeneti könyvtár módosítása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Az annotációk betöltési/mentési helyének módosítása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>&amp;Automatikus mentés</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Automatikus mentés</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Mentés kép adatokkal</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Kép adatok mentése a címke fájlba</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Bezárás</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Jelenlegi fájl bezárása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Előző annotáció megtartása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>&quot;Előző annotáció megtartása&quot; mód váltása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Sokszögek létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Sokszögek rajzolásának megkezdése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Téglalap létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Téglalapok rajzolásának megkezdése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Kör létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Körök rajzolásának megkezdése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Vonal létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Vonalak rajzolásának megkezdése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Pont létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Pontok rajzolásának megkezdése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Vonallánc létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Vonallánc rajzolásának megkezdése. Ctrl+Bal klikk befejezi a létrehozást.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>AI sokszög létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>AI sokszög rajzolásának megkezdése. Ctrl+Bal klikk befejezi a létrehozást.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>AI maszk létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>AI maszk rajzolásának megkezdése. Ctrl+Bal klikk befejezi a létrehozást.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Alakzatok szerkesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>A kijelölt alakzatok mozgatása és szerkesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Alakzatok törlése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>A kijelölt alakzatok törlése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Alakzatok duplikálása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>A kijelölt alakzatok másolatának létrehozása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Alakzatok másolása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Kijelölt alakzatok másolása a vágólapra</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Alakzatok beillesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Másolt alakzatok beillesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Utolsó pont visszavonása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Utolsó rajzolt pont visszavonása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Kijelölt pont eltávolítása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Kijelölt pont eltávolítása a sokszögből</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Visszavonás\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Alakzat utolsó hozzáadásának és szerkesztésének visszavonása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Alakzatok\n&amp;elrejtése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Összes alakzat elrejtése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Alakzatok\n&amp;megjelenítése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Összes alakzat megjelenítése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Alakzatok\n&amp;váltása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Összes alakzat váltása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Oktatóanyag</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Oktatóanyag oldal megjelenítése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Nagyítás</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Kép nagyítása vagy kicsinyítése. A vászonról {} és {} billentyűkkel is elérhető.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Görgő</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Nagyítás</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Nagyítási szint növelése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Kicsinyítés</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Nagyítási szint csökkentése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>&amp;Eredeti méret</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Nagyítás eredeti méretre</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>&amp;Előző méretarány megtartása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Előző nagyítási méretarány megtartása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>&amp;Ablakhoz igazítás</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>A nagyítás követi az ablak méretét</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>&amp;Szélességhez igazítás</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>A nagyítás követi az ablak szélességét</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>&amp;Fényerő/Kontraszt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Fényerő és kontraszt beállítása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Címke szerkesztése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>A kijelölt alakzat címkéjének módosítása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Rajzolt sokszög kitöltése</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Sokszög kitöltése rajzolás közben</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Előző fényerő/kontraszt megtartása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Fájl</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Szerkesztés</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Nézet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Súgó</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>&amp;Legutóbbi megnyitása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s elindítva.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Érvénytelen címke</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Érvénytelen címke '{}' '{}' validációs típussal</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Hiba a címke adatok mentésekor</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Hiba a fájl megnyitásakor</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Nincs ilyen fájl: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>%s betöltése...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Hiba a %s olvasásakor</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Győződjön meg arról, hogy &lt;i&gt;{0}&lt;/i&gt; érvényes kép fájl.&lt;br/&gt;Támogatott kép formátumok: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s betöltve</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Kép és címke fájlok (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Válasszon képet vagy címke fájlt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Annotációk mentése/betöltése könyvtárból</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Az annotációk a %s könyvtárban lesznek mentve/betöltve</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Fájl kiválasztása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Címke fájlok (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Fájl kiválasztása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Biztosan véglegesen törli ezt a címke fájlt?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Figyelem</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Mentse az annotációkat a &quot;{}&quot; fájlba bezárás előtt?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Mentse az annotációkat?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Biztosan véglegesen törli a {} alakzatot?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Könyvtár megnyitása</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Beállítások…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Konfigurációs fájl megnyitása szövegszerkesztőben</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Nincs konfigurációs fájl</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>A konfiguráció YAML kifejezésként lett megadva a parancssorból.\n\nA beállítások szerkesztő használatához indítsa el a Labelme-t konfigurációs fájllal:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Konfigurációs Hibák</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Hibák találhatók a konfiguráció betöltése közben. Kérjük, tekintse át az alábbi hibákat, és töltse újra a konfigurációt, vagy hagyja figyelmen kívül a hibás sorokat.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Győződjön meg arról, hogy &lt;i&gt;%s&lt;/i&gt; érvényes címke fájl.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Győződjön meg arról, hogy &lt;i&gt;%s&lt;/i&gt; érvényes képfájl.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Elrendezés visszaállítása</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/it_IT.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"it_IT\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Annotazione assistita da IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>L'IA suggerisce annotazioni nelle modalità 'AI-Polygon' e 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Seleziona la modalità 'AI-Polygon' o 'AI-Mask' per abilitare l'Annotazione assistita da IA</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>Prompt IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>es. : cane,gatto,uccello</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Esegui</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Punteggio</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>L'IA crea annotazioni dal testo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Seleziona la modalità 'Polygon', 'Rectangle', 'AI-Polygon' o 'AI-Mask' per abilitare</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Clicca e trascina per spostare il punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Clicca e trascina per spostare la forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Creazione di %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC per annullare</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Invio o Spazio per finalizzare</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Modifica delle forme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Clicca sui punti da includere o Maiusc+Clicca per escludere (poligono IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Clicca sui punti da includere o Maiusc+Clicca per escludere (maschera IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Clicca sul punto di partenza della linea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Clicca sul punto finale della linea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Clicca sul punto di partenza della polilinea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Clicca sul punto successivo o Ctrl/Cmd+Clicca per terminare la polilinea</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Clicca sul punto centrale del cerchio</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Clicca su un punto della circonferenza del cerchio</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Clicca sul primo angolo del rettangolo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Clicca per aggiungere un punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + MAIUSC + Clicca per eliminare il punto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Clicca per creare un punto sulla forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Tasto destro e trascina per copiare la forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Clicca sull'angolo opposto del rettangolo (Shift per quadrato)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Flag</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Lista annotazioni</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Seleziona un'etichetta per iniziare ad annotare. Premi 'Esc' per deselezionare.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Lista etichette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Cerca nome file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Lista file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Esci</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Esci dall'applicazione</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Apri\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Apri un'immagine o un file di etichette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Apri directory</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Immagine &amp;successiva</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Apri la successiva (tieni premuto Ctrl+Maiusc per copiare le etichette)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Immagine &amp;precedente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Apri la precedente (tieni premuto Ctrl+Maiusc per copiare le etichette)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Salva\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Salva le etichette in un file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Salva &amp;come</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Salva le etichette in un file diverso</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Elimina file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Elimina il file di etichette corrente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>&amp;Cambia directory di output</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Cambia dove vengono caricate/salvate le annotazioni</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Salva &amp;automaticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Salva automaticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Salva con dati immagine</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Salva i dati dell'immagine nel file di etichette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Chiudi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Chiudi il file corrente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Mantieni annotazione precedente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Crea poligoni</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Inizia a disegnare poligoni</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Crea rettangolo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Inizia a disegnare rettangoli</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Crea cerchio</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Inizia a disegnare cerchi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Crea linea</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Inizia a disegnare linee</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Crea punto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Inizia a disegnare punti</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Crea polilinea</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Inizia a disegnare una polilinea. Ctrl+Clic sinistro termina la creazione.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Crea poligono IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Inizia a disegnare un poligono IA. Ctrl+Clic sinistro termina la creazione.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Crea maschera IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Inizia a disegnare una maschera IA. Ctrl+Clic sinistro termina la creazione.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Modifica forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Sposta e modifica le forme selezionate</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Elimina forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Elimina le forme selezionate</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Duplica forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Crea un duplicato dele forme selezionate</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Copia forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Copia le forme selezionate negli appunti</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Incolla forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Incolla le forme copiate</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Annulla ultimo punto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Annulla l'ultimo punto disegnato</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Rimuovi punto selezionato</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Rimuovi il punto selezionato dal poligono</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Annulla\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Annulla l'ultimo aggiunto e la modifica della forma</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>&amp;Nascondi\nforme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Nascondi tutte le forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>&amp;Mostra\nforme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Mostra tutte le forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>&amp;Commuta\nforme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Commuta tutte le forme</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Mostra la pagina del tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Ingrandisci o riduci l'immagine. Accessibile anche con {} e {} dalla tela.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Rotella</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>Zoom &amp;avanti</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Aumenta il livello di zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>Zoom &amp;indietro</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Diminuisci il livello di zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Dimensione &amp;originale</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Zoom alla dimensione originale</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>&amp;Mantieni scala precedente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Mantieni la scala di zoom precedente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>&amp;Adatta alla finestra</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Lo zoom segue la dimensione della finestra</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Adatta &amp;larghezza</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Lo zoom segue la larghezza della finestra</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>&amp;Luminosità e contrasto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Regola luminosità e contrasto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Modifica etichetta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Modifica l'etichetta della forma selezionata</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Riempire poligono in disegno</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Riempire il poligono durante il disegno</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;File</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Modifica</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Visualizza</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Aiuto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Apri &amp;recenti</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s avviato.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Etichetta non valida</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Etichetta non valida '{}' con tipo di validazione '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Errore nel salvataggio dei dati delle etichette</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Errore nell'apertura del file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>File non trovato : &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Caricamento di %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Errore nella lettura di %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Assicurati che &lt;i&gt;{0}&lt;/i&gt; sia un file immagine valido.&lt;br/&gt;Formati immagine supportati : {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s caricato</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>File Immagine &amp; Etichette (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Scegli un file Immagine o Etichetta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Salva/Carica annotazioni nella directory</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Le annotazioni saranno salvate/caricate in %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Scegli un file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>File di etichette (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Scegli un file</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Stai per eliminare definitivamente questo file di etichette, procedere comunque?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Attenzione</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Salvare le annotazioni in &quot;{}&quot; prima di chiudere?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Salvare le annotazioni?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Stai per eliminare definitivamente {} forme, procedere comunque?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Apri directory</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Attiva/disattiva la modalità &quot;mantieni annotazione precedente&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Mantieni luminosità/contrasto precedenti</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Preferenze…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Apri file di configurazione nell'editor di testo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Nessun file di configurazione</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>La configurazione è stata fornita come espressione YAML tramite riga di comando.\n\nPer utilizzare l'editor delle preferenze, avvia Labelme con un file di configurazione:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Errori di Configurazione</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Sono stati trovati errori durante il caricamento della configurazione. Si prega di esaminare gli errori sottostanti e ricaricare la configurazione o ignorare le righe errate.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Assicurati che &lt;i&gt;%s&lt;/i&gt; sia un file di etichette valido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Assicurati che &lt;i&gt;%s&lt;/i&gt; sia un file di immagine valido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Ripristina layout</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/ja_JP.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"ja_JP\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI支援アノテーション</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AIが'AI-Polygon'と'AI-Mask'モードでアノテーションを提案します</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>「AI-Polygon」または「AI-Mask」モードを選択してAI支援アノテーションを有効化</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AIプロンプト</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>例: dog,cat,bird</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>実行</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>スコア</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AIがテキストプロンプトからアノテーションを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>「Polygon」「Rectangle」「AI-Polygon」「AI-Mask」モードで有効</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>クリック &amp; ドラッグで頂点を移動</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>クリック &amp; ドラッグで図形を移動</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>%r を作成中</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC でキャンセル</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter または Space で確定</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>図形を編集中</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>クリックで含める点を、Shift+クリックで除外する点を指定 (AIポリゴン)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>クリックで含める点を、Shift+クリックで除外する点を指定 (AIマスク)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>直線の始点をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>直線の終点をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>折れ線の始点をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>次の点をクリック、または Ctrl/Cmd+クリックで完了</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>円の中心点をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>円周上の点をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>矩形の最初の角をクリック</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>クリックで頂点を追加</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + クリックで頂点を削除</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + クリックで図形上に頂点を作成</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>右クリック &amp; ドラッグで図形をコピー</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>矩形の対角をクリック（Shiftで正方形）</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>フラグ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>アノテーション一覧</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>ラベルを選択してアノテーションを開始。'Esc' で選択解除。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>ラベル一覧</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>ファイル名で検索</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>ファイル一覧</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>終了(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>アプリケーションを終了</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>開く(&amp;O)\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>画像またはラベルファイルを開く</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>ディレクトリを\n開く</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>次の\n画像(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>次を開く (Ctrl+Shift でラベルをコピー)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>前の\n画像(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>前を開く (Ctrl+Shift でラベルをコピー)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>保存(&amp;S)\n</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>ラベルをファイルに保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>名前を付けて保存(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>ラベルを別のファイルに保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>ファイルを\n削除(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>現在のラベルファイルを削除</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>出力先を変更(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>アノテーションの読み込み/保存先を変更</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>自動保存(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>自動で保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>画像データと共に保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>ラベルファイルに画像データを含める</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>閉じる(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>現在のファイルを閉じる</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>前のアノテーションを保持</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>ポリゴン\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>ポリゴンの描画を開始</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>矩形\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>矩形の描画を開始</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>円\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>円の描画を開始</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>直線\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>直線の描画を開始</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>点\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>点の描画を開始</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>折れ線\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>折れ線の描画を開始。Ctrl+左クリックで完了。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>AIポリゴン\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>AIポリゴンの描画を開始。Ctrl+左クリックで完了。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>AIマスク\nを作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>AIマスクの描画を開始。Ctrl+左クリックで完了。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>図形を\n編集</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>選択した図形を移動・編集</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>図形を\n削除</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>選択した図形を削除</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>図形を\n複製</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>選択した図形の複製を作成</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>図形をコピー</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>選択した図形をクリップボードにコピー</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>図形を貼り付け</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>コピーした図形を貼り付け</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>最後の頂点を取り消し</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>最後に描画した頂点を取り消し</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>選択した頂点を削除</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>ポリゴンから選択した頂点を削除</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>元に戻す</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>最後の図形追加・編集を元に戻す</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>図形を\n非表示(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>すべての図形を非表示</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>図形を\n表示(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>すべての図形を表示</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>図形を\n切り替え(&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>すべての図形の表示を切り替え</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>チュートリアル(&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>チュートリアルページを表示</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>ズーム</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>画像を拡大・縮小します。キャンバス上で {} と {} も使用できます。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+ホイール</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>拡大(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>拡大率を上げる</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>縮小(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>拡大率を下げる</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>原寸大(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>原寸大で表示</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>前の倍率を保持(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>前のズーム倍率を保持</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>ウィンドウに\n合わせる(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>ウィンドウサイズに合わせてズーム</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>幅に合わせる(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>ウィンドウ幅に合わせてズーム</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>明るさ・\nコントラスト(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>明るさとコントラストを調整</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>ラベルを編集(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>選択した図形のラベルを変更</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>描画中のポリゴンを塗りつぶす</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>描画中にポリゴンを塗りつぶす</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>ファイル(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>編集(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>表示(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>ヘルプ(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>最近使用したファイル(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s を起動しました</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>無効なラベル</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>ラベル '{}' は検証タイプ '{}' では無効です</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>ラベルデータの保存エラー</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>ファイルを開けませんでした</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>ファイルが見つかりません: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>%s を読み込み中...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>%s の読み込みエラー</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;i&gt;{0}&lt;/i&gt; が有効な画像ファイルであることを確認してください。&lt;br/&gt;対応形式: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s を読み込みました</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>画像とラベルファイル (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - 画像またはラベルファイルを選択</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - アノテーションの保存/読み込みディレクトリ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s - アノテーションは %s に保存/読み込みされます</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - ファイルを選択</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>ラベルファイル (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>ファイルを選択</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>このラベルファイルを完全に削除します。続行しますか？</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>注意</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>閉じる前にアノテーションを &quot;{}&quot; に保存しますか？</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>アノテーションを保存しますか？</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>{} 個の図形を完全に削除します。続行しますか？</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - ディレクトリを開く</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>「前のアノテーションを保持」モードを切り替え</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>前の明るさ/コントラストを保持</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>設定…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>テキストエディタで設定ファイルを開く</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>設定ファイルがありません</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>設定はコマンドラインからYAML式として提供されました。\n\n設定エディタを使用するには、設定ファイルを指定してLabelmeを起動してください:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>設定エラー</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>設定の読み込み中にエラーが見つかりました。以下のエラーを確認し、設定を再読み込みするか、エラーのある行を無視してください。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;%s&lt;/i&gt; が有効なラベルファイルであることを確認してください。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;%s&lt;/i&gt; が有効な画像ファイルであることを確認してください。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>レイアウトをリセット</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/ko_KR.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"ko_KR\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI 지원 주석</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI가 'AI-Polygon' 및 'AI-Mask' 모드에서 주석을 제안합니다</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>AI 지원 주석을 활성화하려면 'AI-Polygon' 또는 'AI-Mask' 모드를 선택하세요</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI 프롬프트</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>예: 개, 고양이, 새</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>실행</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>점수</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI가 텍스트 프롬프트에서 주석을 생성합니다</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>활성화하려면 'Polygon', 'Rectangle', 'AI-Polygon' 또는 'AI-Mask' 모드를 선택하세요</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>클릭하고 드래그하여 점 이동</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>클릭하고 드래그하여 도형 이동</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>%r 생성 중</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC 키를 눌러 취소</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter 또는 Space로 완료</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>도형 편집 중</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>점을 클릭하여 포함하거나 Shift+클릭하여 제외 (AI 다각형)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>점을 클릭하여 포함하거나 Shift+클릭하여 제외 (AI 마스크)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>선의 시작점 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>선의 끝점 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>연속선의 시작점 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>다음 점을 클릭하거나 Ctrl/Cmd+클릭으로 완료 (연속선)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>원의 중심점 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>원의 둘레 위 점 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>사각형의 첫 번째 모서리 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>점 추가를 위해 클릭</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + 클릭으로 점 삭제</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + 클릭으로 도형 위에 점 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>우클릭하고 드래그하여 도형 복사</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>사각형의 대각 모서리 클릭 (Shift로 정사각형)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>플래그</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>주석 목록</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>주석을 시작할 레이블을 선택하세요. 'Esc'를 눌러 선택 해제합니다.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>레이블 목록</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>파일명 검색</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>파일 목록</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>종료(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>애플리케이션 종료</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>열기(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>이미지 또는 레이블 파일 열기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>폴더 열기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>다음 이미지(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>다음 열기 (Ctrl+Shift를 누르면 레이블 복사)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>이전 이미지(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>이전 열기 (Ctrl+Shift를 누르면 레이블 복사)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>저장(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>레이블을 파일로 저장</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>다른 이름으로 저장(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>레이블을 다른 파일로 저장</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>삭제(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>현재 레이블 파일 삭제</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>출력 폴더 변경(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>주석을 로드/저장할 위치 변경</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>자동 저장(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>자동 저장</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>이미지 데이터와 함께 저장</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>레이블 파일에 이미지 데이터 저장</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>닫기(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>현재 파일 닫기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>이전 주석 유지</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>다각형 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>다각형 그리기 시작</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>사각형 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>사각형 그리기 시작</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>원 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>원 그리기 시작</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>선 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>선 그리기 시작</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>점 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>점 그리기 시작</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>연속선 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>연속선 그리기 시작. Ctrl+좌클릭으로 완료.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>AI 다각형 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>AI 다각형 그리기 시작. Ctrl+좌클릭으로 완료.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>AI 마스크 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>AI 마스크 그리기 시작. Ctrl+좌클릭으로 완료.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>도형 편집</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>선택한 도형 이동 및 편집</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>도형 삭제</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>선택한 도형 삭제</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>도형 복제</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>선택한 도형의 복사본 생성</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>도형 복사</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>선택한 도형을 클립보드에 복사</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>도형 붙여넣기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>복사한 도형 붙여넣기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>마지막 점 실행 취소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>마지막으로 그린 점 실행 취소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>선택한 점 제거</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>다각형에서 선택한 점 제거</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>실행 취소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>도형의 마지막 추가 및 편집 실행 취소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>도형 숨기기(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>모든 도형 숨기기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>도형 표시(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>모든 도형 표시</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>도형 토글(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>모든 도형 토글</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>튜토리얼(&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>튜토리얼 페이지 표시</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>확대/축소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>이미지 확대 또는 축소. 캔버스에서 {} 및 {}로도 접근 가능합니다.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+휠</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>확대(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>확대 수준 증가</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>축소(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>확대 수준 감소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>원본 크기(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>원본 크기로 확대/축소</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>이전 배율 유지(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>이전 확대/축소 배율 유지</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>창에 맞추기(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>확대/축소가 창 크기에 맞춤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>너비에 맞추기(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>확대/축소가 창 너비에 맞춤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>밝기 대비(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>밝기 및 대비 조정</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>레이블 편집(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>선택한 도형의 레이블 수정</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>그리기 다각형 채우기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>그리는 동안 다각형 채우기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>파일(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>편집(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>보기(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>도움말(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>최근 열기(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s가 시작되었습니다.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>잘못된 레이블</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>검증 유형 '{}'에 대한 잘못된 레이블 '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>레이블 데이터 저장 오류</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>파일 열기 오류</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>파일이 없습니다: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>%s 로드 중...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>%s 읽기 오류</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;i&gt;{0}&lt;/i&gt;가 유효한 이미지 파일인지 확인하세요.&lt;br/&gt;지원되는 이미지 형식: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s 로드됨</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>이미지 및 레이블 파일 (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - 이미지 또는 레이블 파일 선택</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - 폴더에 주석 저장/로드</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . 주석이 %s에 저장/로드됩니다</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - 파일 선택</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>레이블 파일 (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>파일 선택</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>이 레이블 파일을 영구적으로 삭제하시겠습니까?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>주의</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>닫기 전에 주석을 &quot;{}&quot;에 저장하시겠습니까?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>주석을 저장하시겠습니까?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>{}개의 도형을 영구적으로 삭제하시겠습니까?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - 폴더 열기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>&quot;이전 주석 유지&quot; 모드 토글</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>이전 밝기/대비 유지</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>환경설정…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>텍스트 편집기에서 설정 파일 열기</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>설정 파일 없음</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>설정이 명령줄에서 YAML 표현식으로 제공되었습니다.\n\n환경설정 편집기를 사용하려면 설정 파일과 함께 Labelme를 시작하세요:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>구성 오류</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>구성을 불러오는 중 오류가 발견되었습니다. 아래 오류를 검토하고 구성을 다시 불러오거나 잘못된 줄을 무시하세요.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;%s&lt;/i&gt;가 유효한 레이블 파일인지 확인하세요.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;%s&lt;/i&gt;가 유효한 이미지 파일인지 확인하세요.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>레이아웃 초기화</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/nl_NL.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"nl_NL\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI-Ondersteunde Annotatie</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI stelt annotatie voor in 'AI-Polygoon' en 'AI-Masker' modi</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Selecteer 'AI-Polygoon' of 'AI-Masker' modus om AI-Ondersteunde Annotatie in te schakelen</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI Tekst-naar-Annotatie</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI maakt annotaties van de tekstprompt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>bijv. hond, kat, vogel</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Uitvoeren</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Score</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Selecteer 'Polygoon', 'Rechthoek', 'AI-Polygoon' of 'AI-Masker' modus om in te schakelen</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Klik en sleep om punt te verplaatsen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Klik en sleep om vorm te verplaatsen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Maken van %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC om te annuleren</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter of Spatie om te voltooien</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Vormen bewerken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Klik op punten om op te nemen of Shift+Klik om uit te sluiten (AI-polygoon)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Klik op punten om op te nemen of Shift+Klik om uit te sluiten (AI-masker)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Klik op startpunt voor lijn</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Klik op eindpunt voor lijn</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Klik op startpunt voor lijnstrook</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Klik op volgend punt of Ctrl/Cmd+Klik om te voltooien (lijnstrook)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Klik op middelpunt voor cirkel</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Klik op punt op omtrek voor cirkel</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Klik op eerste hoek voor rechthoek</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Klik om punt toe te voegen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Klik om punt te verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Klik om punt op vorm te maken</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Rechtsklik en sleep om vorm te kopiëren</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Klik op tegenoverliggende hoek voor rechthoek (Shift voor vierkant)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Vlaggen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Annotatielijst</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Selecteer label om te beginnen met annoteren. Druk op 'Esc' om te deselecteren.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Labellijst</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Zoek Bestandsnaam</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Bestandslijst</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Afsluiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Applicatie afsluiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Openen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Afbeelding of labelbestand openen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Map Openen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Volgende &amp;Afbeelding</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Volgende openen (houd Ctrl+Shift ingedrukt om labels te kopiëren)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Vorige &amp;Afbeelding</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Vorige openen (houd Ctrl+Shift ingedrukt om labels te kopiëren)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Opslaan</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Labels opslaan naar bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Opslaan &amp;als</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Labels opslaan naar ander bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>Bestand &amp;verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Huidig labelbestand verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>Uitvoermap &amp;wijzigen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Wijzig waar annotaties worden geladen/opgeslagen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>&amp;Automatisch opslaan</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Automatisch opslaan</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Opslaan met Afbeeldingsgegevens</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Afbeeldingsgegevens opslaan in labelbestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Sluiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Huidig bestand sluiten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Vorige Annotatie Behouden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Polygonen Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Begin met tekenen van polygonen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Rechthoek Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Begin met tekenen van rechthoeken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Cirkel Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Begin met tekenen van cirkels</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Lijn Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Begin met tekenen van lijnen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Punt Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Begin met tekenen van punten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Lijnstrook Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Begin met tekenen van lijnstrook. Ctrl+Linkerklik beëindigt het maken.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>AI-Polygoon Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Begin met tekenen van AI-polygoon. Ctrl+Linkerklik beëindigt het maken.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>AI-Masker Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Begin met tekenen van AI-masker. Ctrl+Linkerklik beëindigt het maken.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Vormen Bewerken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Verplaats en bewerk de geselecteerde vormen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Vormen Verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Geselecteerde vormen verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Vormen Dupliceren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Maak een duplicaat van de geselecteerde vormen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Vormen Kopiëren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Geselecteerde vormen naar klembord kopiëren</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Vormen Plakken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Gekopieerde vormen plakken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Laatste punt ongedaan maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Laatste getekende punt ongedaan maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Geselecteerd Punt Verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Geselecteerd punt uit polygoon verwijderen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Ongedaan Maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Laatste toevoeging en bewerking van vorm ongedaan maken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Vormen &amp;verbergen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Alle vormen verbergen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Vormen &amp;tonen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Alle vormen tonen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Vormen &amp;omschakelen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Alle vormen omschakelen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Tutorialpagina tonen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>In- of uitzoomen op de afbeelding. Ook toegankelijk met {} en {} vanaf het canvas.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Wiel</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Inzoomen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Zoomniveau verhogen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Uitzoomen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Zoomniveau verlagen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>&amp;Originele grootte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Zoomen naar originele grootte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Vorige Schaal &amp;behouden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Vorige zoomschaal behouden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>Aanpassen aan &amp;venster</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Zoom volgt venstergrootte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Aanpassen aan &amp;breedte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Zoom volgt vensterbreedte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>Helderheid en &amp;contrast</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Helderheid en contrast aanpassen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>Label &amp;bewerken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Label van geselecteerde vorm wijzigen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Polygoon Vullen bij Tekenen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Polygoon vullen tijdens tekenen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Bewerken</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Beeld</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Help</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Open &amp;recent</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s gestart.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Ongeldig label</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Ongeldig label '{}' met validatietype '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Fout bij opslaan van labelgegevens</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Fout bij openen van bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Bestand niet gevonden: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Laden van %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Fout bij lezen van %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Zorg ervoor dat &lt;i&gt;{0}&lt;/i&gt; een geldig afbeeldingsbestand is.&lt;br/&gt;Ondersteunde afbeeldingsformaten: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>Geladen %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Afbeelding- en labelbestanden (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Kies Afbeelding- of labelbestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Annotaties Opslaan/Laden in Map</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Annotaties worden opgeslagen/geladen in %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Kies Bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Labelbestanden (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Kies Bestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>U staat op het punt dit labelbestand permanent te verwijderen, doorgaan?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Let op</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Annotaties opslaan naar &quot;{}&quot; voordat u sluit?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Annotaties opslaan?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>U staat op het punt {} vormen permanent te verwijderen, doorgaan?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Map Openen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Modus &quot;vorige annotatie behouden&quot; omschakelen</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Vorige Helderheid/Contrast Behouden</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Voorkeuren…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Configuratiebestand openen in teksteditor</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Geen configuratiebestand</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>De configuratie is als YAML-expressie via de opdrachtregel opgegeven.\n\nOm de voorkeureneditor te gebruiken, start Labelme met een configuratiebestand:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Configuratiefouten</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Er zijn fouten gevonden bij het laden van de configuratie. Bekijk de onderstaande fouten en herlaad uw configuratie of negeer de foutieve regels.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Zorg ervoor dat &lt;i&gt;%s&lt;/i&gt; een geldig labelbestand is.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Zorg ervoor dat &lt;i&gt;%s&lt;/i&gt; een geldig afbeeldingsbestand is.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Layout herstellen</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/pl_PL.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"pl_PL\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Adnotacja wspomagana przez AI</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI sugeruje adnotacje w trybach 'AI-Polygon' i 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Wybierz tryb 'AI-Polygon' lub 'AI-Mask', aby włączyć adnotację wspomaganą przez AI</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI — tekst na adnotację</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>np. pies,kot,ptak</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Uruchom</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Wynik</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI tworzy adnotacje na podstawie podanego tekstu</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Wybierz tryb 'Polygon', 'Rectangle', 'AI-Polygon' lub 'AI-Mask', aby włączyć</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Kliknij i przeciągnij, aby przesunąć punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Kliknij i przeciągnij, aby przesunąć kształt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Tworzenie %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC — anuluj</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter lub Spacja — zatwierdź</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Edycja kształtów</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Kliknij punkty, aby dołączyć, lub Shift+Klik, aby wykluczyć (ai_polygon)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Kliknij punkty, aby dołączyć, lub Shift+Klik, aby wykluczyć (ai_mask)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Kliknij punkt początkowy linii</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Kliknij punkt końcowy linii</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Kliknij punkt początkowy polilinii</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Kliknij następny punkt lub Ctrl/Cmd+Klik, aby zakończyć polilinię</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Kliknij środek okręgu</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Kliknij punkt na obwodzie okręgu</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Kliknij pierwszy róg prostokąta</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Kliknij, aby dodać punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Klik — usuń punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Klik — utwórz punkt na kształcie</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Prawy przycisk i przeciągnij — skopiuj kształt</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Kliknij przeciwległy róg prostokąta (Shift — kwadrat)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Flagi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Lista adnotacji</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Wybierz etykietę, aby zacząć adnotację. Naciśnij 'Esc', aby odznaczyć.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Lista etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Szukaj nazwy pliku</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Lista plików</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Zakończ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Zamknij aplikację</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Otwórz</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Otwórz obraz lub plik etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Otwórz folder</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>&amp;Następny obraz</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Otwórz następny (Ctrl+Shift — kopiuj etykiety)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>&amp;Poprzedni obraz</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Otwórz poprzedni (Ctrl+Shift — kopiuj etykiety)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Zapisz</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Zapisz etykiety do pliku</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Zapisz &amp;jako</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Zapisz etykiety do innego pliku</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Usuń plik</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Usuń bieżący plik etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>&amp;Zmień folder wynikowy</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Zmień miejsce wczytywania/zapisywania adnotacji</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Zapisuj &amp;automatycznie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Zapisuj automatycznie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Zapisz z danymi obrazu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Zapisz dane obrazu w pliku etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Zamknij</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Zamknij bieżący plik</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Zachowaj poprzednią adnotację</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Utwórz wielokąty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Rozpocznij rysowanie wielokątów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Utwórz prostokąt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Rozpocznij rysowanie prostokątów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Utwórz okrąg</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Rozpocznij rysowanie okręgów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Utwórz linię</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Rozpocznij rysowanie linii</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Utwórz punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Rozpocznij rysowanie punktów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Utwórz polilinię</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Rozpocznij rysowanie polilinii. Ctrl+Klik lewy kończy tworzenie.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Utwórz AI-wielokąt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Rozpocznij rysowanie ai_polygon. Ctrl+Klik lewy kończy tworzenie.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Utwórz maskę AI</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Rozpocznij rysowanie ai_mask. Ctrl+Klik lewy kończy tworzenie.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Edytuj kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Przesuń i edytuj zaznaczone kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Usuń kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Usuń zaznaczone kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Duplikuj kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Utwórz duplikat zaznaczonych kształtów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Kopiuj kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Kopiuj zaznaczone kształty do schowka</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Wklej kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Wklej skopiowane kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Cofnij ostatni punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Cofnij ostatnio narysowany punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Usuń zaznaczony punkt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Usuń zaznaczony punkt z wielokąta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Cofnij</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Cofnij ostatnie dodanie i edycję kształtu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>&amp;Ukryj kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Ukryj wszystkie kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>&amp;Pokaż kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Pokaż wszystkie kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Przełącz &amp;kształty</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Przełącz widoczność wszystkich kształtów</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Samouczek</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Pokaż stronę samouczka</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Powiększenie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Powiększ lub pomniejsz obraz. Dostępne także przez {} i {} na płótnie.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+kółko</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>Powiększ (&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Zwiększ powiększenie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>Pomniejsz (&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Zmniejsz powiększenie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Oryginalny rozmiar (&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Powiększ do oryginalnego rozmiaru</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Zachowaj poprzednią skalę (&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Zachowaj poprzednią skalę powiększenia</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>Dopasuj do okna (&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Powiększenie dopasowane do rozmiaru okna</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Dopasuj szerokość (&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Powiększenie dopasowane do szerokości okna</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>Jasność i kontrast (&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Dostosuj jasność i kontrast</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Edytuj etykietę</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Zmień etykietę zaznaczonego kształtu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Wypełnij rysowany wielokąt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Wypełniaj wielokąt podczas rysowania</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Plik</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Edycja</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Widok</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Pomoc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Otwórz &amp;ostatnie</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s uruchomiono.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Nieprawidłowa etykieta</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Nieprawidłowa etykieta '{}' dla typu walidacji '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Błąd zapisu etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Błąd otwarcia pliku</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Brak pliku: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Wczytywanie %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Upewnij się, że &lt;i&gt;%s&lt;/i&gt; jest prawidłowym plikiem etykiet.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Błąd odczytu %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Upewnij się, że &lt;i&gt;{0}&lt;/i&gt; jest prawidłowym plikiem obrazu.&lt;br/&gt;Obsługiwane formaty: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>Wczytano %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Pliki obrazów i etykiet (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s — Wybierz plik obrazu lub etykiet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s — Zapisz/wczytaj adnotacje w folderze</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s. Adnotacje będą zapisywane/wczytywane w %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s — Wybierz plik</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Pliki etykiet (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Wybierz plik</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Czy na pewno trwale usunąć ten plik etykiet?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Uwaga</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Zapisać adnotacje do &quot;{}&quot; przed zamknięciem?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Zapisać adnotacje?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Czy na pewno trwale usunąć {} kształtów?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s — Otwórz folder</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Przełącz tryb „zachowaj poprzednią adnotację”</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Zachowaj poprzednią jasność/kontrast</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Preferencje…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Otwórz plik konfiguracji w edytorze tekstu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Brak pliku konfiguracji</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>Konfiguracja została podana w linii poleceń jako wyrażenie YAML.\n\nAby użyć edytora preferencji, uruchom Labelme z plikiem konfiguracji:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Błędy konfiguracji</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Wystąpiły błędy podczas wczytywania konfiguracji. Sprawdź listę poniżej i przeładuj konfigurację lub zignoruj błędne wiersze.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Upewnij się, że &lt;i&gt;%s&lt;/i&gt; jest prawidłowym plikiem obrazu.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Zresetuj układ</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/pt_BR.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"pt_BR\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Anotação Assistida por IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>IA sugere anotação nos modos 'Polígono IA' e 'Máscara IA'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Selecione o modo 'Polígono IA' ou 'Máscara IA' para ativar a Anotação Assistida por IA</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>Texto para Anotação IA</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>IA cria anotações a partir do prompt de texto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>ex.: cachorro, gato, pássaro</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Executar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Pontuação</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Selecione o modo 'Polígono', 'Retângulo', 'Polígono IA' ou 'Máscara IA' para ativar</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Clique e arraste para mover o ponto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Clique e arraste para mover a forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Criando %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>ESC para cancelar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Enter ou Espaço para finalizar</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Editando formas</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Clique nos pontos para incluir ou Shift+Clique para excluir (polígono IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Clique nos pontos para incluir ou Shift+Clique para excluir (máscara IA)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Clique no ponto inicial da linha</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Clique no ponto final da linha</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Clique no ponto inicial da linha contínua</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Clique no próximo ponto ou Ctrl/Cmd+Clique para finalizar (linha contínua)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Clique no ponto central do círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Clique em um ponto da circunferência do círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Clique na primeira esquina do retângulo</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Clique para adicionar um ponto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Clique para excluir o ponto</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Clique para criar um ponto na forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Clique com o botão direito e arraste para copiar a forma</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Clique na esquina oposta do retângulo (Shift para quadrado)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Marcadores</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Lista de Anotações</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Selecione um rótulo para começar a anotar. Pressione 'Esc' para desmarcar.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Lista de Rótulos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Buscar Nome do Arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Lista de Arquivos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Sair</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Sair do aplicativo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Abrir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Abrir arquivo de imagem ou rótulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Abrir Diretório</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Imagem &amp;Seguinte</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Abrir seguinte (mantenha Ctrl+Shift para copiar rótulos)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Imagem &amp;Anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Abrir anterior (mantenha Ctrl+Shift para copiar rótulos)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Salvar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Salvar rótulos no arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Salvar &amp;Como</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Salvar rótulos em um arquivo diferente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>&amp;Excluir Arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Excluir arquivo de rótulo atual</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>Alterar Diretório de &amp;Saída</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Alterar onde as anotações são carregadas/salvas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Salvar &amp;Automaticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Salvar automaticamente</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Salvar com Dados da Imagem</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Salvar dados da imagem no arquivo de rótulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Fechar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Fechar arquivo atual</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Manter Anotação Anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Criar Polígonos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Começar a desenhar polígonos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Criar Retângulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Começar a desenhar retângulos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Criar Círculo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Começar a desenhar círculos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Criar Linha</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Começar a desenhar linhas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Criar Ponto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Começar a desenhar pontos</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Criar Linha Contínua</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Começar a desenhar linha contínua. Ctrl+Clique esquerdo finaliza a criação.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Criar Polígono IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Começar a desenhar polígono IA. Ctrl+Clique esquerdo finaliza a criação.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Criar Máscara IA</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Começar a desenhar máscara IA. Ctrl+Clique esquerdo finaliza a criação.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Editar Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Mover e editar as formas selecionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Excluir Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Excluir as formas selecionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Duplicar Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Criar uma cópia das formas selecionadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Copiar Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Copiar formas selecionados para a área de transferência</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Colar Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Colar formas copiadas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Desfazer último ponto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Desfazer último ponto desenhado</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Remover Ponto Selecionado</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Remover ponto selecionado do polígono</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Desfazer</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Desfazer última adição e edição de forma</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Ocultar &amp;Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Ocultar todas as formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Mostrar &amp;Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Mostrar todas as formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Alternar &amp;Formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Alternar todas as formas</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Mostrar página do tutorial</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Aproximar ou afastar a imagem. Também acessível com {} e {} a partir da tela.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Roda</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Aproximar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Aumentar nível de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Afastar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Diminuir nível de zoom</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Tamanho &amp;Original</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Zoom para o tamanho original</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Manter Escala &amp;Anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Manter escala de zoom anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>Ajustar à &amp;Janela</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>O zoom segue o tamanho da janela</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Ajustar à &amp;Largura</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>O zoom segue a largura da janela</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>Brilho e &amp;Contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Ajustar brilho e contraste</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>&amp;Editar Rótulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Modificar o rótulo da forma selecionada</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Preencher Polígono ao Desenhar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Preencher polígono enquanto desenha</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Editar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Visualizar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Ajuda</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Abrir &amp;Recentes</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s iniciado.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Rótulo inválido</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Rótulo inválido '{}' com tipo de validação '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Erro ao salvar dados do rótulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Erro ao abrir arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Arquivo não encontrado: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Carregando %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Erro ao ler %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Certifique-se de que &lt;i&gt;{0}&lt;/i&gt; seja um arquivo de imagem válido.&lt;br/&gt;Formatos de imagem suportados: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>Carregado %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Arquivos de Imagem e Rótulo (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Escolher Arquivo de Imagem ou Rótulo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Salvar/Carregar Anotações no Diretório</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . As anotações serão salvas/carregadas em %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Escolher Arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Arquivos de rótulo (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Escolher Arquivo</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Você está prestes a excluir permanentemente este arquivo de rótulo, continuar mesmo assim?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Atenção</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Salvar anotações em &quot;{}&quot; antes de fechar?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Salvar anotações?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Você está prestes a excluir permanentemente {} formas, continuar mesmo assim?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Abrir Diretório</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Alternar modo &quot;manter anotação anterior&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Manter Brilho/Contraste Anterior</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Preferências…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Abrir arquivo de configuração no editor de texto</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Sem arquivo de configuração</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>A configuração foi fornecida como uma expressão YAML via linha de comando.\n\nPara usar o editor de preferências, inicie o Labelme com um arquivo de configuração:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Erros de Configuração</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Foram encontrados erros ao carregar a configuração. Por favor, revise os erros abaixo e recarregue sua configuração ou ignore as linhas com erro.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Certifique-se de que &lt;i&gt;%s&lt;/i&gt; seja um arquivo de rótulo válido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Certifique-se de que &lt;i&gt;%s&lt;/i&gt; seja um arquivo de imagem válido.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Redefinir layout</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/th_TH.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"th_TH\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>แอนโนเทชันด้วย AI</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI แนะนำแอนโนเทชันในโหมด 'AI-Polygon' และ 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>เลือกโหมด 'AI-Polygon' หรือ 'AI-Mask' เพื่อเปิดใช้แอนโนเทชันด้วย AI</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI ข้อความสู่แอนโนเทชัน</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>เช่น สุนัข, แมว, นก</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>รัน</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>คะแนน</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI สร้างแอนโนเทชันจากข้อความที่ป้อน</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>เลือกโหมด 'Polygon', 'Rectangle', 'AI-Polygon' หรือ 'AI-Mask' เพื่อเปิดใช้</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>คลิกและลากเพื่อย้ายจุด</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>คลิกและลากเพื่อย้ายรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>กำลังสร้าง %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>กด ESC เพื่อยกเลิก</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>กด Enter หรือ Space เพื่อยืนยัน</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>แก้ไขรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>คลิกจุดเพื่อรวม หรือ Shift+คลิกเพื่อยกเว้น สำหรับ ai_polygon</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>คลิกจุดเพื่อรวม หรือ Shift+คลิกเพื่อยกเว้น สำหรับ ai_mask</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>คลิกจุดเริ่มต้นของเส้น</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>คลิกจุดสิ้นสุดของเส้น</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>คลิกจุดเริ่มต้นของเส้นต่อเนื่อง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>คลิกจุดถัดไป หรือ Ctrl/Cmd+คลิกเพื่อจบเส้นต่อเนื่อง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>คลิกจุดศูนย์กลางของวงกลม</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>คลิกจุดบนเส้นรอบวงของวงกลม</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>คลิกมุมแรกของสี่เหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>คลิกเพื่อเพิ่มจุด</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + คลิกเพื่อลบจุด</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + คลิกเพื่อสร้างจุดบนรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>คลิกขวาและลากเพื่อคัดลอกรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>คลิกมุมตรงข้ามของสี่เหลี่ยม (Shift สำหรับสี่เหลี่ยมจัตุรัส)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>แฟล็ก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>รายการแอนโนเทชัน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>เลือกเลเบลเพื่อเริ่มกำกับข้อมูล กด 'Esc' เพื่อยกเลิกการเลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>รายการเลเบล</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>ค้นหาชื่อไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>รายการไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>ออก (&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>ปิดแอป</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>เปิด (&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>เปิดรูปหรือไฟล์เลเบล</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>เปิดโฟลเดอร์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>รูปถัดไป (&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>เปิดรูปถัดไป (กด Ctrl+Shift เพื่อคัดลอกเลเบล)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>รูปก่อนหน้า (&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>เปิดรูปก่อนหน้า (กด Ctrl+Shift เพื่อคัดลอกเลเบล)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>บันทึก (&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>บันทึกเลเบลลงไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>บันทึกเป็น (&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>บันทึกเลเบลไปยังไฟล์อื่น</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>ลบไฟล์ (&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>ลบไฟล์เลเบลปัจจุบัน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>เปลี่ยนโฟลเดอร์ผลลัพธ์ (&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>เปลี่ยนโฟลเดอร์สำหรับโหลด/บันทึกแอนโนเทชัน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>บันทึกอัตโนมัติ (&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>บันทึกอัตโนมัติ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>บันทึกพร้อมข้อมูลรูป</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>บันทึกข้อมูลรูปในไฟล์เลเบล</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>ปิด (&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>ปิดไฟล์ปัจจุบัน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>คงแอนโนเทชันก่อนหน้า</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>สร้างหลายเหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>เริ่มวาดหลายเหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>สร้างสี่เหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>เริ่มวาดสี่เหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>สร้างวงกลม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>เริ่มวาดวงกลม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>สร้างเส้น</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>เริ่มวาดเส้น</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>สร้างจุด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>เริ่มวาดจุด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>สร้างเส้นต่อเนื่อง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>เริ่มวาดเส้นต่อเนื่อง Ctrl+คลิกซ้ายเพื่อจบ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>สร้าง AI-หลายเหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>เริ่มวาด ai_polygon Ctrl+คลิกซ้ายเพื่อจบ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>สร้าง AI-มาสก์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>เริ่มวาด ai_mask Ctrl+คลิกซ้ายเพื่อจบ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>แก้ไขรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>ย้ายและแก้ไขรูปร่างที่เลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>ลบรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>ลบรูปร่างที่เลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>ทำซ้ำรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>สร้างสำเนารูปร่างที่เลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>คัดลอกรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>คัดลอกรูปร่างที่เลือกไปคลิปบอร์ด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>วางรูปร่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>วางรูปร่างที่คัดลอก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>ยกเลิกจุดล่าสุด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>ยกเลิกจุดที่วาดล่าสุด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>ลบจุดที่เลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>ลบจุดที่เลือกออกจากหลายเหลี่ยม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>ยกเลิก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>ยกเลิกการเพิ่มและแก้ไขรูปร่างล่าสุด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>ซ่อนรูปร่าง (&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>ซ่อนรูปร่างทั้งหมด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>แสดงรูปร่าง (&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>แสดงรูปร่างทั้งหมด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>สลับรูปร่าง (&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>สลับรูปร่างทั้งหมด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>บทแนะนำ (&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>แสดงหน้าบทแนะนำ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>ซูม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>ซูมเข้า-ออกของรูป ใช้ {} และ {} ที่แคนวาสได้เช่นกัน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+ล้อเลื่อน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>ซูมเข้า (&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>เพิ่มระดับซูม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>ซูมออก (&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>ลดระดับซูม</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>ขนาดจริง (&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>ซูมเป็นขนาดจริง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>คงระดับซูมก่อนหน้า (&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>คงระดับซูมก่อนหน้า</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>พอดีหน้าต่าง (&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>ซูมตามขนาดหน้าต่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>พอดีความกว้าง (&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>ซูมตามความกว้างหน้าต่าง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>ความสว่าง คอนทราสต์ (&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>ปรับความสว่างและคอนทราสต์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>แก้ไขเลเบล (&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>แก้ไขเลเบลของรูปร่างที่เลือก</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>เติมสีหลายเหลี่ยมที่วาด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>เติมสีหลายเหลี่ยมขณะวาด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>ไฟล์ (&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>แก้ไข (&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>มุมมอง (&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>ช่วยเหลือ (&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>เปิดล่าสุด (&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s เริ่มทำงานแล้ว</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>เลเบลไม่ถูกต้อง</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>เลเบล '{}' ไม่ถูกต้อง ประเภทการตรวจ '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>เกิดข้อผิดพลาดในการบันทึกข้อมูลเลเบล</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>เกิดข้อผิดพลาดในการเปิดไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>ไม่มีไฟล์: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>กำลังโหลด %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>เกิดข้อผิดพลาดในการอ่าน %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;ตรวจสอบว่า &lt;i&gt;{0}&lt;/i&gt; เป็นไฟล์รูปที่ถูกต้อง&lt;br/&gt;รูปแบบรูปที่รองรับ: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>โหลด %s แล้ว</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>ไฟล์รูปและเลเบล (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - เลือกรูปหรือไฟล์เลเบล</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - บันทึก/โหลดแอนโนเทชันในโฟลเดอร์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s แอนโนเทชันจะถูกบันทึก/โหลดใน %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - เลือกไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>ไฟล์เลเบล (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>เลือกไฟล์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>คุณกำลังจะลบไฟล์เลเบลนี้อย่างถาวร ต้องการดำเนินการต่อหรือไม่?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>คำเตือน</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>บันทึกแอนโนเทชันไปที่ &quot;{}&quot; ก่อนปิดหรือไม่?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>บันทึกแอนโนเทชันหรือไม่?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>คุณกำลังจะลบรูปร่าง {} รายการอย่างถาวร ต้องการดำเนินการต่อหรือไม่?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - เปิดโฟลเดอร์</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>สลับโหมด &quot;คงแอนโนเทชันก่อนหน้า&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>คงความสว่าง/คอนทราสต์ก่อนหน้า</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>การตั้งค่า…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>เปิดไฟล์ตั้งค่าในโปรแกรมแก้ไขข้อความ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>ไม่มีไฟล์ตั้งค่า</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>การตั้งค่าถูกกำหนดเป็น YAML ผ่านบรรทัดคำสั่ง\n\nหากต้องการใช้ตัวแก้ไขการตั้งค่า ให้เริ่ม Labelme ด้วยไฟล์ config:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>ข้อผิดพลาดการตั้งค่า</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>พบข้อผิดพลาดขณะโหลดการตั้งค่า กรุณาตรวจสอบด้านล่าง แล้วโหลดการตั้งค่าใหม่หรือข้ามบรรทัดที่มีข้อผิดพลาด</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;ตรวจสอบว่า &lt;i&gt;%s&lt;/i&gt; เป็นไฟล์เลเบลที่ถูกต้อง&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;ตรวจสอบว่า &lt;i&gt;%s&lt;/i&gt; เป็นไฟล์รูปที่ถูกต้อง&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>รีเซ็ตเค้าโครง</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/tr_TR.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"tr_TR\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI Destekli Etiketleme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI, 'AI-Polygon' ve 'AI-Mask' modlarında etiketleme önerir</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>AI Destekli Etiketlemeyi etkinleştirmek için 'AI-Polygon' veya 'AI-Mask' modunu seçin</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI Metinden Etiketleme</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>örn., köpek,kedi,kuş</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Çalıştır</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Skor</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI, metin isteminden etiketlemeler oluşturur</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Etkinleştirmek için 'Polygon', 'Rectangle', 'AI-Polygon' veya 'AI-Mask' modunu seçin</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Noktayı taşımak için tıkla ve sürükle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Şekli taşımak için tıkla ve sürükle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>%r oluşturuluyor</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>İptal için ESC</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Bitirmek için Enter veya Space</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Şekiller düzenleniyor</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>ai_polygon için noktaları dahil etmek için tıkla, hariç tutmak için Shift+tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>ai_mask için noktaları dahil etmek için tıkla, hariç tutmak için Shift+tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Çizgi için başlangıç noktasına tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Çizgi için bitiş noktasına tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Çizgi şeridi için başlangıç noktasına tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Çizgi şeridi için sonraki noktaya tıkla veya Ctrl/Cmd+tıkla ile bitir</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Daire için merkez noktaya tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Daire için çevre üzerindeki bir noktaya tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Dikdörtgen için ilk köşeye tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Nokta eklemek için tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>Noktayı silmek için ALT + SHIFT + tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>Şekil üzerinde nokta oluşturmak için ALT + tıkla</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Şekli kopyalamak için sağ tıkla ve sürükle</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Dikdörtgen için karşı köşeye tıkla (kare için Shift)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Bayraklar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Etiketleme Listesi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Etiketlemeye başlamak için bir etiket seçin. Seçimi kaldırmak için 'Esc' tuşuna basın.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Etiket Listesi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Dosya Adı Ara</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Dosya Listesi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>&amp;Çıkış</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Uygulamadan çık</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>&amp;Aç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Görüntü veya etiket dosyası aç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Dizin Aç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>&amp;Sonraki Görüntü</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Sonrakini aç (etiketleri kopyalamak için Ctrl+Shift basılı tutun)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>&amp;Önceki Görüntü</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Öncekini aç (etiketleri kopyalamak için Ctrl+Shift basılı tutun)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>&amp;Kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Etiketleri dosyaya kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Farklı &amp;Kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Etiketleri farklı bir dosyaya kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>Dosyayı &amp;Sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Geçerli etiket dosyasını sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>Çıktı Dizinini &amp;Değiştir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Etiketlemelerin yüklendiği/kaydedildiği yeri değiştir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Otomatik &amp;Kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Otomatik kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Görüntü Verisiyle Kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Görüntü verisini etiket dosyasında kaydet</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>&amp;Kapat</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Geçerli dosyayı kapat</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Önceki Etiketlemeyi Koru</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Çokgen Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Çokgen çizmeye başla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Dikdörtgen Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Dikdörtgen çizmeye başla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Daire Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Daire çizmeye başla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Çizgi Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Çizgi çizmeye başla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Nokta Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Nokta çizmeye başla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Çizgi Şeridi Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Çizgi şeridi çizmeye başla. Ctrl+Sol Tık ile oluşturmayı bitirir.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>AI-Polygon Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>ai_polygon çizmeye başla. Ctrl+Sol Tık ile oluşturmayı bitirir.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>AI-Mask Oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>ai_mask çizmeye başla. Ctrl+Sol Tık ile oluşturmayı bitirir.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Şekilleri Düzenle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Seçili şekilleri taşı ve düzenle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Şekilleri Sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Seçili şekilleri sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Şekilleri Çoğalt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Seçili şekillerin kopyasını oluştur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Şekilleri Kopyala</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Seçili şekilleri panoya kopyala</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Şekilleri Yapıştır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Kopyalanan şekilleri yapıştır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Son noktayı geri al</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Çizilen son noktayı geri al</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Seçili Noktayı Sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Seçili noktayı çokgenden sil</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Geri Al</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Şeklin son ekleme ve düzenlemesini geri al</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Şekilleri &amp;Gizle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Tüm şekilleri gizle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Şekilleri &amp;Göster</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Tüm şekilleri göster</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Şekilleri &amp;Aç/Kapat</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Tüm şekilleri aç/kapat</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>&amp;Öğretici</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Öğretici sayfasını göster</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Yakınlaştırma</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Görüntüyü yakınlaştır veya uzaklaştır. Tuvalde {} ve {} ile de erişilebilir.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Tekerlek</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>&amp;Yakınlaştır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Yakınlaştırma seviyesini artır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>&amp;Uzaklaştır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Yakınlaştırma seviyesini azalt</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>&amp;Orijinal boyut</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Orijinal boyuta getir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Önceki Ölçeği &amp;Koru</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Önceki yakınlaştırma ölçeğini koru</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>&amp;Pencereye Sığdır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Yakınlaştırma pencere boyutunu izler</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>&amp;Genişliğe Sığdır</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Yakınlaştırma pencere genişliğini izler</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>&amp;Parlaklık Kontrast</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Parlaklık ve kontrastı ayarla</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>Etiketi &amp;Düzenle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Seçili şeklin etiketini değiştir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Çizerken Çokgeni Doldur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Çizerken çokgeni doldur</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>&amp;Dosya</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>&amp;Düzenle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>&amp;Görünüm</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>&amp;Yardım</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>&amp;Son Açılanlar</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s başlatıldı.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Geçersiz etiket</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Doğrulama türü '{}' olan '{}' etiketi geçersiz</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Etiket verisi kaydedilirken hata</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Dosya açma hatası</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Böyle bir dosya yok: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>%s yükleniyor...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>%s okunurken hata</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Lütfen &lt;i&gt;{0}&lt;/i&gt; geçerli bir görüntü dosyası olduğundan emin olun.&lt;br/&gt;Desteklenen görüntü biçimleri: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>%s yüklendi</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Görüntü ve Etiket dosyaları (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Görüntü veya Etiket dosyası seç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Dizinde Etiketlemeleri Kaydet/Yükle</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Etiketlemeler %s içinde kaydedilecek/yüklenecek</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Dosya Seç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Etiket dosyaları (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Dosya Seç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Bu etiket dosyasını kalıcı olarak silmek üzeresiniz, yine de devam edilsin mi?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Dikkat</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Kapatmadan önce etiketlemeler &quot;{}&quot; konumuna kaydedilsin mi?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Etiketlemeler kaydedilsin mi?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>{} şekli kalıcı olarak silmek üzeresiniz, yine de devam edilsin mi?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Dizini Aç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>&quot;önceki etiketlemeyi koru&quot; modunu değiştir</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Önceki Parlaklık/Kontrastı Koru</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Tercihler…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Yapılandırma dosyasını metin düzenleyicide aç</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Yapılandırma Dosyası Yok</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>Yapılandırma, komut satırı üzerinden bir YAML ifadesi olarak sağlandı.\n\nTercihler düzenleyicisini kullanmak için Labelme'i bir yapılandırma dosyasıyla başlatın:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Yapılandırma Hataları</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Yapılandırma yüklenirken hatalar bulundu. Lütfen aşağıdaki hataları inceleyin ve yapılandırmayı yeniden yükleyin ya da hatalı satırları yok sayın.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Lütfen &lt;i&gt;%s&lt;/i&gt; geçerli bir etiket dosyası olduğundan emin olun.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Lütfen &lt;i&gt;%s&lt;/i&gt; geçerli bir görüntü dosyası olduğundan emin olun.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Düzeni sıfırla</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/vi_VN.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"vi_VN\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>Chú thích dữ liệu với sự hỗ trợ của AI</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI đề xuất chú thích ở chế độ 'AI-Polygon' và 'AI-Mask'</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>Chọn chế độ 'AI-Polygon' hoặc 'AI-Mask' để bật Chú thích hỗ trợ AI</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI Văn bản sang Chú thích</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>ví dụ: chó,mèo,chim</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>Chạy</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>Điểm số</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI tạo chú thích từ lời nhắc văn bản</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>Chọn chế độ 'Polygon', 'Rectangle', 'AI-Polygon' hoặc 'AI-Mask' để bật</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>Nhấn và kéo để di chuyển điểm</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>Nhấn và kéo để di chuyển hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>Đang tạo %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>Nhấn ESC để hủy</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>Nhấn Enter hoặc Space để hoàn tất</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>Chỉnh sửa hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>Nhấn điểm để bao gồm hoặc Shift+Nhấn để loại trừ cho ai_polygon</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>Nhấn điểm để bao gồm hoặc Shift+Nhấn để loại trừ cho ai_mask</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>Nhấn điểm bắt đầu cho đường thẳng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>Nhấn điểm kết thúc cho đường thẳng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>Nhấn điểm bắt đầu cho đường gấp khúc</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>Nhấn điểm tiếp theo hoặc hoàn tất bằng Ctrl/Cmd+Nhấn cho đường gấp khúc</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>Nhấn điểm trung tâm cho hình tròn</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>Nhấn điểm trên chu vi cho hình tròn</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>Nhấn góc đầu tiên cho hình chữ nhật</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>Nhấn để thêm điểm</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + Nhấn để xóa điểm</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + Nhấn để tạo điểm trên hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>Nhấn chuột phải và kéo để sao chép hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>Nhấn góc đối diện cho hình chữ nhật (Shift để tạo hình vuông)</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>Cờ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>Danh sách Chú thích</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>Chọn nhãn để bắt đầu chú thích. Nhấn 'Esc' để bỏ chọn.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>Danh sách Nhãn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>Tìm kiếm Tên tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>Danh sách Tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>Thoát(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>Thoát ứng dụng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>Mở(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>Mở tệp hình ảnh hoặc nhãn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>Mở Thư mục</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>Hình ảnh Tiếp theo(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>Mở tiếp theo (giữ Ctl+Shift để sao chép nhãn)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>Hình ảnh Trước(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>Mở trước đó (giữ Ctl+Shift để sao chép nhãn)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>Lưu(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>Lưu nhãn vào tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>Lưu thành(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>Lưu nhãn vào tệp khác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>Xóa(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>Xóa tệp nhãn hiện tại</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>Thay đổi Thư mục Đầu ra(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>Thay đổi nơi chú thích được tải/lưu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>Tự động lưu (&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>Tự động lưu</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>Lưu với Dữ liệu Hình ảnh</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>Lưu dữ liệu hình ảnh trong tệp nhãn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>Đóng(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>Đóng tệp hiện tại</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>Giữ Chú thích Trước đó</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>Tạo Đa giác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>Bắt đầu vẽ đa giác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>Tạo Hình chữ nhật</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>Bắt đầu vẽ hình chữ nhật</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>Tạo Hình tròn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>Bắt đầu vẽ hình tròn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>Tạo Đường thẳng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>Bắt đầu vẽ đường thẳng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>Tạo Điểm</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>Bắt đầu vẽ điểm</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>Tạo Đường gấp khúc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>Bắt đầu vẽ đường gấp khúc. Ctrl+Nhấn chuột trái để kết thúc tạo.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>Tạo AI-Đa giác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>Bắt đầu vẽ ai_polygon. Ctrl+Nhấn chuột trái để kết thúc tạo.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>Tạo AI-Mask</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>Bắt đầu vẽ ai_mask. Ctrl+Nhấn chuột trái để kết thúc tạo.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>Chỉnh sửa Hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>Di chuyển và chỉnh sửa các hình dạng đã chọn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>Xóa Hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>Xóa các hình dạng đã chọn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>Nhân đôi Hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>Tạo bản sao của các hình dạng đã chọn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>Sao chép Hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>Sao chép các hình dạng đã chọn vào clipboard</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>Dán Hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>Dán các hình dạng đã sao chép</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>Hoàn tác điểm cuối cùng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>Hoàn tác điểm vẽ cuối cùng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>Xóa Điểm đã Chọn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>Xóa điểm đã chọn khỏi đa giác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>Hoàn tác</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>Hoàn tác lần thêm và chỉnh sửa hình dạng cuối cùng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>Ẩn Hình dạng(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>Ẩn tất cả hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>Hiển thị Hình dạng(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>Hiển thị tất cả hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>Bật/tắt Hình dạng(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>Bật/tắt tất cả hình dạng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>Hướng dẫn(&amp;T)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>Hiển thị trang hướng dẫn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>Thu phóng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>Phóng to hoặc thu nhỏ hình ảnh. Cũng có thể truy cập bằng {} và {} từ canvas.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+Bánh xe</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>Phóng to(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>Tăng mức thu phóng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>Thu nhỏ(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>Giảm mức thu phóng</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>Kích thước Gốc(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>Thu phóng về kích thước gốc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>Giữ Tỷ lệ Trước đó(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>Giữ tỷ lệ thu phóng trước đó</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>Vừa Cửa sổ(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>Thu phóng theo kích thước cửa sổ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>Vừa Chiều rộng(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>Thu phóng theo chiều rộng cửa sổ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>Độ sáng Độ tương phản(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>Điều chỉnh độ sáng và độ tương phản</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>Chỉnh sửa Nhãn(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>Sửa đổi nhãn của hình dạng đã chọn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>Tô Đa giác Vẽ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>Tô đa giác khi vẽ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>Tệp(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>Chỉnh sửa(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>Xem(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>Trợ giúp(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>Mở Gần đây(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s đã khởi động.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>Nhãn không hợp lệ</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>Nhãn không hợp lệ '{}' với loại xác thực '{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>Lỗi khi lưu dữ liệu nhãn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>Lỗi khi mở tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>Không có tệp như vậy: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>Đang tải %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>Lỗi khi đọc %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;Đảm bảo &lt;i&gt;{0}&lt;/i&gt; là tệp hình ảnh hợp lệ.&lt;br/&gt;Các định dạng hình ảnh được hỗ trợ: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>Đã tải %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>Tệp Hình ảnh &amp; Nhãn (%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - Chọn tệp Hình ảnh hoặc Nhãn</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - Lưu/Tải Chú thích trong Thư mục</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . Chú thích sẽ được lưu/tải trong %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - Chọn Tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>Tệp nhãn (*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>Chọn Tệp</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>Bạn sắp xóa vĩnh viễn tệp nhãn này, có tiếp tục không?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>Chú ý</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>Lưu chú thích vào &quot;{}&quot; trước khi đóng?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>Lưu chú thích?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>Bạn sắp xóa vĩnh viễn {} hình dạng, có tiếp tục không?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - Mở Thư mục</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>Bật/tắt chế độ &quot;giữ chú thích trước đó&quot;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>Giữ Độ sáng/Độ tương phản Trước đó</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>Tùy chọn…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>Mở tệp cấu hình trong trình soạn thảo văn bản</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>Lỗi Cấu hình</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>Đã tìm thấy lỗi khi tải cấu hình. Vui lòng xem lại các lỗi bên dưới và tải lại cấu hình hoặc bỏ qua các dòng bị lỗi.</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>Không có Tệp Cấu hình</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>Cấu hình được cung cấp dưới dạng biểu thức YAML qua dòng lệnh.\n\nĐể sử dụng trình chỉnh sửa tùy chọn, khởi động Labelme với tệp cấu hình:\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Đảm bảo &lt;i&gt;%s&lt;/i&gt; là tệp nhãn hợp lệ.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Đảm bảo &lt;i&gt;%s&lt;/i&gt; là tệp hình ảnh hợp lệ.&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>Đặt lại bố cục</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/zh_CN.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"zh_CN\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI辅助标注</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI在'AI-Polygon'和'AI-Mask'模式下提供标注建议</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>选择「AI-Polygon」或「AI-Mask」模式以启用AI辅助标注</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI提示</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>例如：狗,猫,鸟</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>运行</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>分数</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI根据文本提示创建标注</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>选择 'Polygon'、'Rectangle'、'AI-Polygon' 或 'AI-Mask' 模式以启用</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>点击并拖拽以移动控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>点击并拖拽以移动形状</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>正在创建 %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>按 ESC 取消</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>按 Enter 或空格键完成</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>编辑形状</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>点击以包含点或 Shift+点击以排除点(AI多边形)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>点击以包含点或 Shift+点击以排除点(AI蒙版)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>点击线段起点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>点击线段终点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>点击折线起点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>点击下一个点或 Ctrl/Cmd+点击完成折线</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>点击圆形中心点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>点击圆周上的点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>点击矩形第一个角</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>点击以添加点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + 点击以删除点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + 点击在形状上创建点</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>右键点击并拖拽以复制形状</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>点击矩形对角（Shift绘制正方形）</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>标记</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>批注列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>选择标签类型并开始以其标注。按'Esc'取消选择。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>标签列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>按文件名检索</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>文件列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>退出(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>退出应用</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>打开(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>打开图像或标签文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>打开目录</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>下一幅(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>打开下一幅 (按Ctl+Shift拷贝标签)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>上一幅(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>打开上一幅 (按Ctl+Shift拷贝标签)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>保存(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>保存标签到文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>另存为(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>保存标签到不同的文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>删除(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>删除当前标签文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>更改输出路径(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>更改载入、保存标注的路径</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>自动保存(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>自动保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>同时保存图像数据</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>将图像数据保存到标签文件中</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>关闭(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>关闭当前文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>保留最后的标注</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>创建多边形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>开始绘制多边形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>创建矩形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>开始绘制矩形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>创建圆形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>开始绘制圆形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>创建直线</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>开始创建直线</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>创建控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>开始绘制控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>创建折线</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>开始绘制折线。Ctrl+单击左键结束绘制。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>创建AI多边形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>开始绘制AI多边形。Ctrl+单击左键结束绘制。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>创建AI蒙版</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>开始绘制AI蒙版。Ctrl+单击左键结束绘制。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>编辑图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>移动、编辑选中的图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>删除图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>删除选中的图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>复制图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>为选中的图形创建副本</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>复制图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>复制选中图形到剪贴板</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>粘贴图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>粘贴已复制的图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>撤销最后的控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>撤销最后一次绘制的控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>移除选中的控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>从多边形中移除选中的控制点</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>撤销</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>撤销最近一次添加和编辑</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>隐藏图形(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>隐藏所有图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>显示图形(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>显示所有图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>开关图形(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>开关所有图形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>教程[&amp;T]</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>显示教程网页</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>缩放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>缩放图像。亦可从画布的{}和{}访问</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+滚轮</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>放大(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>增加缩放水平</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>缩小(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>减小缩放水平</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>原始大小(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>缩放至原始大小</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>保留最后的比例(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>保留最后的缩放比例</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>适应窗口(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>跟随窗口大小缩放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>适应宽度(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>跟随窗口宽度缩放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>亮度 对比度(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>调节亮度和对比度</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>编辑标签(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>修改选中图形的标签</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>填充所绘多边形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>绘制时填充多边形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>文件(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>编辑(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>视图(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>帮助(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>最近打开(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s 启动完了</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>无效的标签</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>无效的标签'{}'，验证类型'{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>保存标签发生错误</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>打开文件发生错误</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>文件不存在: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>正在载入 %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>打开文件发生错误 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>lt;p&gt;请确认&lt;i&gt;{0}&lt;/i&gt;是一个合法的图像文件。&lt;br/&gt;支持的格式包括: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>已加载 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>图像和标签文件(%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - 选择图像或标签文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - 保存和加载批注的路径</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . 批注会被加载和保存在 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - 选择文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>标签文件(*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>选择文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>即将永久性删除此标签文件。还要继续吗?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>注意</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>关闭前保存批注到&quot;{}&quot;吗?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>保存批注吗?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>即将永久性删除图形{}。还要继续吗?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - 打开目录</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>切换「保留上一个标注」模式</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>保留之前的亮度/对比度</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>偏好设置…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>在文本编辑器中打开配置文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>没有配置文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>配置已通过命令行以YAML表达式的形式提供。\n\n要使用偏好设置编辑器，请使用配置文件启动Labelme：\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>配置错误</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>加载配置时发现错误。请检查以下错误并重新加载配置，或忽略错误的行。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;请确认&lt;i&gt;%s&lt;/i&gt;是一个合法的标签文件。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;请确认&lt;i&gt;%s&lt;/i&gt;是一个合法的图像文件。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>重置布局</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/translate/zh_TW.ts",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE TS>\n<TS version=\"2.1\" language=\"zh_TW\">\n<context>\n    <name>AiAssistedAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI-Assisted Annotation</source>\n        <translation>AI輔助標註</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>AI suggests annotation in &apos;AI-Polygon&apos; and &apos;AI-Mask&apos; modes</source>\n        <translation>AI在'AI-Polygon'和'AI-Mask'模式下提供標註建議</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_assisted_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;AI-Polygon&apos; or &apos;AI-Mask&apos; mode to enable AI-Assisted Annotation</source>\n        <translation>選擇「AI-Polygon」或「AI-Mask」模式以啟用AI輔助標註</translation>\n    </message>\n</context>\n<context>\n    <name>AiTextToAnnotationWidget</name>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI Text-to-Annotation</source>\n        <translation>AI提示</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>e.g., dog,cat,bird</source>\n        <translation>例如：狗,貓,鳥</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Run</source>\n        <translation>執行</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Score</source>\n        <translation>分數</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>IoU</source>\n        <translation>IoU</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>AI creates annotations from the text prompt</source>\n        <translation>AI根據文字提示創建標註</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/_ai_text_to_annotation_widget.py\" line=\"0\"/>\n        <source>Select &apos;Polygon&apos;, &apos;Rectangle&apos;, &apos;AI-Polygon&apos;, or &apos;AI-Mask&apos; mode to enable</source>\n        <translation>選擇 'Polygon'、'Rectangle'、'AI-Polygon' 或 'AI-Mask' 模式以啟用</translation>\n    </message>\n</context>\n<context>\n    <name>Canvas</name>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move point</source>\n        <translation>點擊並拖拽以移動控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click &amp; drag to move shape</source>\n        <translation>點擊並拖拽以移動形狀</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Creating %r</source>\n        <translation>正在創建 %r</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ESC to cancel</source>\n        <translation>按 ESC 取消</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Enter or Space to finalize</source>\n        <translation>按 Enter 或空格鍵完成</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Editing shapes</source>\n        <translation>編輯形狀</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_polygon</source>\n        <translation>點擊以包含點或 Shift+點擊以排除點(AI多邊形)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click points to include or Shift+Click to exclude for ai_mask</source>\n        <translation>點擊以包含點或 Shift+點擊以排除點(AI蒙版)</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for line</source>\n        <translation>點擊線段起點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click end point for line</source>\n        <translation>點擊線段終點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click start point for linestrip</source>\n        <translation>點擊折線起點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click next point or finish by Ctrl/Cmd+Click for linestrip</source>\n        <translation>點擊下一個點或 Ctrl/Cmd+點擊完成折線</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click center point for circle</source>\n        <translation>點擊圓形中心點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click point on circumference for circle</source>\n        <translation>點擊圓周上的點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click first corner for rectangle</source>\n        <translation>點擊矩形第一個角</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click to add point</source>\n        <translation>點擊以添加點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + SHIFT + Click to delete point</source>\n        <translation>ALT + SHIFT + 點擊以刪除點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>ALT + Click to create point on shape</source>\n        <translation>ALT + 點擊在形狀上創建點</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Right-click &amp; drag to copy shape</source>\n        <translation>右鍵點擊並拖拽以複製形狀</translation>\n    </message>\n    <message>\n        <location filename=\"../widgets/canvas.py\" line=\"0\"/>\n        <source>Click opposite corner for rectangle (Shift for square)</source>\n        <translation>點擊矩形對角（Shift繪製正方形）</translation>\n    </message>\n</context>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Flags</source>\n        <translation>標記</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Annotation List</source>\n        <translation>批註列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Select label to start annotating for it. Press &apos;Esc&apos; to deselect.</source>\n        <translation>選擇標籤類型並開始以其標註。按'Esc'取消選擇。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label List</source>\n        <translation>標籤列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Search Filename</source>\n        <translation>按文件名檢索</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>File List</source>\n        <translation>文件列表</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Quit</source>\n        <translation>退出(&amp;Q)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Quit application</source>\n        <translation>退出應用</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Open\n</source>\n        <translation>打開(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open image or label file</source>\n        <translation>打開圖像或標籤文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open Dir</source>\n        <translation>打開目錄</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Next Image</source>\n        <translation>下一幅(&amp;N)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open next (hold Ctl+Shift to copy labels)</source>\n        <translation>打開下一幅（按 Ctrl+Shift 複製標籤）</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Prev Image</source>\n        <translation>上一幅(&amp;P)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open prev (hold Ctl+Shift to copy labels)</source>\n        <translation>打開上一幅（按 Ctrl+Shift 複製標籤）</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save\n</source>\n        <translation>保存(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to file</source>\n        <translation>保存標籤到文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Save As</source>\n        <translation>另存為(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save labels to a different file</source>\n        <translation>保存標籤到不同的文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Delete File</source>\n        <translation>刪除(&amp;D)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete current label file</source>\n        <translation>刪除當前標籤文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Change Output Dir</source>\n        <translation>更改輸出路徑(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Change where annotations are loaded/saved</source>\n        <translation>更改載入、保存標註的路徑</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save &amp;Automatically</source>\n        <translation>自動保存(&amp;A)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save automatically</source>\n        <translation>自動保存</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save With Image Data</source>\n        <translation>同時保存圖像數據</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save image data in label file</source>\n        <translation>將圖像數據保存到標籤文件中</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Close</source>\n        <translation>關閉(&amp;C)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Close current file</source>\n        <translation>關閉當前文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Annotation</source>\n        <translation>保留上一個標註</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Polygons</source>\n        <translation>創建多邊形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing polygons</source>\n        <translation>開始繪製多邊形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Rectangle</source>\n        <translation>創建矩形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing rectangles</source>\n        <translation>開始繪製矩形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Circle</source>\n        <translation>創建圓形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing circles</source>\n        <translation>開始繪製圓形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Line</source>\n        <translation>創建直線</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing lines</source>\n        <translation>開始繪製直線</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create Point</source>\n        <translation>創建控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing points</source>\n        <translation>開始繪製控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create LineStrip</source>\n        <translation>創建折線</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing linestrip. Ctrl+LeftClick ends creation.</source>\n        <translation>開始繪製折線。Ctrl+單擊左鍵結束繪製。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Polygon</source>\n        <translation>創建AI多邊形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_polygon. Ctrl+LeftClick ends creation.</source>\n        <translation>開始繪製AI多邊形。Ctrl+單擊左鍵結束繪製。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create AI-Mask</source>\n        <translation>創建AI蒙版</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Start drawing ai_mask. Ctrl+LeftClick ends creation.</source>\n        <translation>開始繪製AI蒙版。Ctrl+單擊左鍵結束繪製。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Edit Shapes</source>\n        <translation>編輯圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Move and edit the selected shapes</source>\n        <translation>移動、編輯選中的圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete Shapes</source>\n        <translation>刪除圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Delete the selected shapes</source>\n        <translation>刪除選中的圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Duplicate Shapes</source>\n        <translation>複製圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Create a duplicate of the selected shapes</source>\n        <translation>為選中的圖形創建副本</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy Shapes</source>\n        <translation>複製圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Copy selected shapes to clipboard</source>\n        <translation>複製選中圖形到剪貼板</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste Shapes</source>\n        <translation>粘貼圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Paste copied shapes</source>\n        <translation>粘貼已複製的圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last point</source>\n        <translation>撤銷最後的控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last drawn point</source>\n        <translation>撤銷最後一次繪製的控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove Selected Point</source>\n        <translation>移除選中的控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Remove selected point from polygon</source>\n        <translation>從多邊形中移除選中的控制點</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo\n</source>\n        <translation>撤銷</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Undo last add and edit of shape</source>\n        <translation>撤銷最近一次添加和編輯</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Hide\nShapes</source>\n        <translation>隱藏圖形(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Hide all shapes</source>\n        <translation>隱藏所有圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Show\nShapes</source>\n        <translation>顯示圖形(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show all shapes</source>\n        <translation>顯示所有圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Toggle\nShapes</source>\n        <translation>開關圖形(&amp;S)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle all shapes</source>\n        <translation>開關所有圖形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Tutorial</source>\n        <translation>教程[&amp;T]</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Show tutorial page</source>\n        <translation>顯示教程網頁</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom</source>\n        <translation>縮放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom in or out of the image. Also accessible with {} and {} from the canvas.</source>\n        <translation>縮放圖像。亦可從畫布的{}和{}訪問</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Ctrl+Wheel</source>\n        <translation>Ctrl+滾輪</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom &amp;In</source>\n        <translation>放大(&amp;I)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Increase zoom level</source>\n        <translation>增加縮放水平</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Zoom Out</source>\n        <translation>縮小(&amp;Z)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Decrease zoom level</source>\n        <translation>減小縮放水平</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Original size</source>\n        <translation>原始大小(&amp;O)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom to original size</source>\n        <translation>縮放至原始大小</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Keep Previous Scale</source>\n        <translation>保留上一個比例(&amp;K)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep previous zoom scale</source>\n        <translation>保留上一個縮放比例</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Fit Window</source>\n        <translation>適應窗口(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window size</source>\n        <translation>跟隨窗口大小縮放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fit &amp;Width</source>\n        <translation>適應寬度(&amp;W)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Zoom follows window width</source>\n        <translation>跟隨窗口寬度縮放</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Brightness Contrast</source>\n        <translation>亮度 對比度(&amp;B)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Adjust brightness and contrast</source>\n        <translation>調節亮度和對比度</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit Label</source>\n        <translation>編輯標籤(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Modify the label of the selected shape</source>\n        <translation>修改選中圖形的標籤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill Drawing Polygon</source>\n        <translation>填充所繪多邊形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Fill polygon while drawing</source>\n        <translation>繪製時填充多邊形</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;File</source>\n        <translation>文件(&amp;F)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Edit</source>\n        <translation>編輯(&amp;E)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;View</source>\n        <translation>視圖(&amp;V)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&amp;Help</source>\n        <translation>幫助(&amp;H)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open &amp;Recent</source>\n        <translation>最近打開(&amp;R)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s started.</source>\n        <translation>%s 已啟動</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label</source>\n        <translation>無效的標籤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Invalid label &apos;{}&apos; with validation type &apos;{}&apos;</source>\n        <translation>無效的標籤'{}'，驗證類型'{}'</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error saving label data</source>\n        <translation>保存標籤發生錯誤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>&lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error opening file</source>\n        <translation>打開文件發生錯誤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No such file: &lt;b&gt;%s&lt;/b&gt;</source>\n        <translation>文件不存在: &lt;b&gt;%s&lt;/b&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loading %s...</source>\n        <translation>正在載入 %s...</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Error reading %s</source>\n        <translation>打開文件發生錯誤 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;Make sure &lt;i&gt;{0}&lt;/i&gt; is a valid image file.&lt;br/&gt;Supported image formats: {1}&lt;/p&gt;</source>\n        <translation>&lt;p&gt;請確認&lt;i&gt;{0}&lt;/i&gt;是一個合法的圖像文件。&lt;br/&gt;支援的格式包括: {1}&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Loaded %s</source>\n        <translation>已載入 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Image &amp; Label files (%s)</source>\n        <translation>圖像和標籤文件(%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose Image or Label file</source>\n        <translation>%s - 選擇圖像或標籤文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Save/Load Annotations in Directory</source>\n        <translation>%s - 保存和載入批註的路徑</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s . Annotations will be saved/loaded in %s</source>\n        <translation>%s . 批註會被載入和保存在 %s</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Choose File</source>\n        <translation>%s - 選擇文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Label files (*%s)</source>\n        <translation>標籤文件(*%s)</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Choose File</source>\n        <translation>選擇文件</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete this label file, proceed anyway?</source>\n        <translation>即將永久性刪除此標籤文件。還要繼續嗎?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Attention</source>\n        <translation>注意</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations to &quot;{}&quot; before closing?</source>\n        <translation>關閉前保存批註到&quot;{}&quot;嗎?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Save annotations?</source>\n        <translation>保存批註嗎?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>You are about to permanently delete {} shapes, proceed anyway?</source>\n        <translation>即將永久性刪除圖形{}。還要繼續嗎?</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>%s - Open Directory</source>\n        <translation>%s - 打開目錄</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Toggle &quot;keep previous annotation&quot; mode</source>\n        <translation>開關「保留上一個標註」模式</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Keep Previous Brightness/Contrast</source>\n        <translation>保留之前的亮度/對比度</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Preferences…</source>\n        <translation>偏好設定…</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Open config file in text editor</source>\n        <translation>在文字編輯器中開啟設定檔</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>No Config File</source>\n        <translation>沒有設定檔</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration was provided as a YAML expression via command line.\n\nTo use the preferences editor, start Labelme with a config file:\n  labelme --config ~/.labelmerc</source>\n        <translation>設定已透過命令列以YAML表達式的形式提供。\n\n要使用偏好設定編輯器，請使用設定檔啟動Labelme：\n  labelme --config ~/.labelmerc</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Configuration Errors</source>\n        <translation>設定錯誤</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines.</source>\n        <translation>載入設定時發現錯誤。請檢查以下錯誤並重新載入設定，或忽略錯誤的行。</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid label file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;請確認&lt;i&gt;%s&lt;/i&gt;是一個合法的標籤文件。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Make sure &lt;i&gt;%s&lt;/i&gt; is a valid image file.&lt;/p&gt;</source>\n        <translation>&lt;p&gt;&lt;b&gt;%s&lt;/b&gt;&lt;/p&gt;&lt;p&gt;請確認&lt;i&gt;%s&lt;/i&gt;是一個合法的圖像文件。&lt;/p&gt;</translation>\n    </message>\n    <message>\n        <location filename=\"../app.py\" line=\"0\"/>\n        <source>Reset Layout</source>\n        <translation>重置佈局</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "labelme/utils/__init__.py",
    "content": "from ._io import lblsave\nfrom .image import apply_exif_orientation\nfrom .image import img_arr_to_b64\nfrom .image import img_arr_to_data\nfrom .image import img_b64_to_arr\nfrom .image import img_data_to_arr\nfrom .image import img_data_to_pil\nfrom .image import img_data_to_png_data\nfrom .image import img_pil_to_data\nfrom .image import img_qt_to_arr\nfrom .qt import addActions\nfrom .qt import distance\nfrom .qt import distancetoline\nfrom .qt import fmtShortcut\nfrom .qt import labelValidator\nfrom .qt import newAction\nfrom .qt import newButton\nfrom .qt import newIcon\nfrom .shape import masks_to_bboxes\nfrom .shape import shape_to_mask\nfrom .shape import shapes_to_label\n"
  },
  {
    "path": "labelme/utils/_io.py",
    "content": "# MIT License\n# Copyright (c) Kentaro Wada\n\nimport os.path as osp\n\nimport numpy as np\nimport PIL.Image\n\n\ndef lblsave(filename, lbl):\n    import imgviz\n\n    if osp.splitext(filename)[1] != \".png\":\n        filename += \".png\"\n    # Assume label ranses [-1, 254] for int32,\n    # and [0, 255] for uint8 as VOC.\n    if lbl.min() >= -1 and lbl.max() < 255:\n        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode=\"P\")\n        colormap = imgviz.label_colormap()\n        lbl_pil.putpalette(colormap.flatten())\n        lbl_pil.save(filename)\n    else:\n        raise ValueError(\n            f\"[{filename}] Cannot save the pixel-wise class label as PNG. \"\n            \"Please consider using the .npy format.\"\n        )\n"
  },
  {
    "path": "labelme/utils/image.py",
    "content": "# MIT License\n# Copyright (c) Kentaro Wada\n\nimport base64\nimport io\n\nimport numpy as np\nimport PIL.ExifTags\nimport PIL.Image\nimport PIL.ImageOps\n\n\ndef img_data_to_pil(img_data):\n    f = io.BytesIO()\n    f.write(img_data)\n    img_pil = PIL.Image.open(f)\n    return img_pil\n\n\ndef img_data_to_arr(img_data):\n    img_pil = img_data_to_pil(img_data)\n    img_arr = np.array(img_pil)\n    return img_arr\n\n\ndef img_b64_to_arr(img_b64):\n    img_data = base64.b64decode(img_b64)\n    img_arr = img_data_to_arr(img_data)\n    return img_arr\n\n\ndef img_pil_to_data(img_pil):\n    f = io.BytesIO()\n    img_pil.save(f, format=\"PNG\")\n    img_data = f.getvalue()\n    return img_data\n\n\ndef img_arr_to_b64(img_arr):\n    img_data = img_arr_to_data(img_arr)\n    img_b64 = base64.b64encode(img_data).decode(\"utf-8\")\n    return img_b64\n\n\ndef img_arr_to_data(img_arr):\n    img_pil = PIL.Image.fromarray(img_arr)\n    img_data = img_pil_to_data(img_pil)\n    return img_data\n\n\ndef img_data_to_png_data(img_data):\n    with io.BytesIO() as f:\n        f.write(img_data)\n        img = PIL.Image.open(f)\n\n        with io.BytesIO() as f:\n            img.save(f, \"PNG\")\n            f.seek(0)\n            return f.read()\n\n\ndef img_qt_to_arr(img_qt):\n    w, h, d = img_qt.size().width(), img_qt.size().height(), img_qt.depth()\n    bytes_ = img_qt.bits().asstring(w * h * d // 8)\n    img_arr = np.frombuffer(bytes_, dtype=np.uint8).reshape((h, w, d // 8))\n    return img_arr\n\n\ndef apply_exif_orientation(image):\n    try:\n        exif = image._getexif()\n    except AttributeError:\n        exif = None\n\n    if exif is None:\n        return image\n\n    exif = {PIL.ExifTags.TAGS[k]: v for k, v in exif.items() if k in PIL.ExifTags.TAGS}\n\n    orientation = exif.get(\"Orientation\", None)\n\n    if orientation == 1:\n        # do nothing\n        return image\n    elif orientation == 2:\n        # left-to-right mirror\n        return PIL.ImageOps.mirror(image)\n    elif orientation == 3:\n        # rotate 180\n        return image.transpose(PIL.Image.ROTATE_180)\n    elif orientation == 4:\n        # top-to-bottom mirror\n        return PIL.ImageOps.flip(image)\n    elif orientation == 5:\n        # top-to-left mirror\n        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_270))\n    elif orientation == 6:\n        # rotate 270\n        return image.transpose(PIL.Image.ROTATE_270)\n    elif orientation == 7:\n        # top-to-right mirror\n        return PIL.ImageOps.mirror(image.transpose(PIL.Image.ROTATE_90))\n    elif orientation == 8:\n        # rotate 90\n        return image.transpose(PIL.Image.ROTATE_90)\n    else:\n        return image\n"
  },
  {
    "path": "labelme/utils/qt.py",
    "content": "import os.path as osp\nfrom math import sqrt\n\nimport numpy as np\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\nhere = osp.dirname(osp.abspath(__file__))\n\n\ndef newIcon(icon_file_name: str) -> QtGui.QIcon:\n    if osp.splitext(icon_file_name)[1] == \"\":\n        icon_file_name = f\"{icon_file_name}.png\"  # XXX: convention\n    icons_dir: str = osp.join(here, \"../icons\")\n    return QtGui.QIcon(osp.join(\":/\", icons_dir, icon_file_name))\n\n\ndef newButton(text, icon=None, slot=None):\n    b = QtWidgets.QPushButton(text)\n    if icon is not None:\n        b.setIcon(newIcon(icon))\n    if slot is not None:\n        b.clicked.connect(slot)\n    return b\n\n\ndef newAction(\n    parent,\n    text,\n    slot=None,\n    shortcut=None,\n    icon=None,\n    tip=None,\n    checkable=False,\n    enabled=True,\n    checked=False,\n):\n    \"\"\"Create a new action and assign callbacks, shortcuts, etc.\"\"\"\n    a = QtWidgets.QAction(text, parent)\n    if icon is not None:\n        a.setIconText(text.replace(\" \", \"\\n\"))\n        a.setIcon(newIcon(icon))\n    if shortcut is not None:\n        if isinstance(shortcut, list | tuple):\n            a.setShortcuts(shortcut)\n        else:\n            a.setShortcut(shortcut)\n    if tip is not None:\n        a.setToolTip(tip)\n        a.setStatusTip(tip)\n    if slot is not None:\n        a.triggered.connect(slot)\n    if checkable:\n        a.setCheckable(True)\n    a.setEnabled(enabled)\n    a.setChecked(checked)\n    return a\n\n\ndef addActions(widget, actions):\n    for action in actions:\n        if action is None:\n            widget.addSeparator()\n        elif isinstance(action, QtWidgets.QMenu):\n            widget.addMenu(action)\n        else:\n            widget.addAction(action)\n\n\ndef labelValidator():\n    return QtGui.QRegExpValidator(QtCore.QRegExp(r\"^[^ \\t].+\"), None)\n\n\ndef distance(p):\n    return sqrt(p.x() * p.x() + p.y() * p.y())\n\n\ndef distancetoline(point, line):\n    p1, p2 = line\n    p1 = np.array([p1.x(), p1.y()])\n    p2 = np.array([p2.x(), p2.y()])\n    p3 = np.array([point.x(), point.y()])\n    if np.dot((p3 - p1), (p2 - p1)) < 0:\n        return np.linalg.norm(p3 - p1)\n    if np.dot((p3 - p2), (p1 - p2)) < 0:\n        return np.linalg.norm(p3 - p2)\n    d = p2 - p1\n    if np.linalg.norm(d) == 0:\n        return np.linalg.norm(p3 - p1)\n    v = p1 - p3\n    cross = d[0] * v[1] - d[1] * v[0]\n    return abs(cross) / np.linalg.norm(d)\n\n\ndef fmtShortcut(text):\n    mod, key = text.split(\"+\", 1)\n    return f\"<b>{mod}</b>+<b>{key}</b>\"\n"
  },
  {
    "path": "labelme/utils/shape.py",
    "content": "# MIT License\n# Copyright (c) Kentaro Wada\n\nimport math\nimport uuid\n\nimport numpy as np\nimport PIL.Image\nimport PIL.ImageDraw\nfrom numpy.typing import NDArray\n\n\ndef shape_to_mask(\n    img_shape: tuple[int, ...],\n    points: list[list[float]],\n    shape_type: str | None = None,\n    line_width: int = 10,\n    point_size: int = 5,\n) -> NDArray[np.bool_]:\n    mask = PIL.Image.fromarray(np.zeros(img_shape[:2], dtype=np.uint8))\n    draw = PIL.ImageDraw.Draw(mask)\n    xy = [tuple(point) for point in points]\n    if shape_type == \"circle\":\n        assert len(xy) == 2, \"Shape of shape_type=circle must have 2 points\"\n        (cx, cy), (px, py) = xy\n        d = math.sqrt((cx - px) ** 2 + (cy - py) ** 2)\n        draw.ellipse([cx - d, cy - d, cx + d, cy + d], outline=1, fill=1)\n    elif shape_type == \"rectangle\":\n        assert len(xy) == 2, \"Shape of shape_type=rectangle must have 2 points\"\n        (x0, y0), (x1, y1) = xy\n        draw.rectangle(\n            ((min(x0, x1), min(y0, y1)), (max(x0, x1), max(y0, y1))),\n            outline=1,\n            fill=1,\n        )\n    elif shape_type == \"line\":\n        assert len(xy) == 2, \"Shape of shape_type=line must have 2 points\"\n        draw.line(xy=xy, fill=1, width=line_width)  # type: ignore[arg-type]\n    elif shape_type == \"linestrip\":\n        draw.line(xy=xy, fill=1, width=line_width)  # type: ignore[arg-type]\n    elif shape_type == \"point\":\n        assert len(xy) == 1, \"Shape of shape_type=point must have 1 points\"\n        cx, cy = xy[0]\n        r = point_size\n        draw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=1, fill=1)\n    elif shape_type in [None, \"polygon\"]:\n        assert len(xy) > 2, \"Polygon must have points more than 2\"\n        draw.polygon(xy=xy, outline=1, fill=1)  # type: ignore[arg-type]\n    else:\n        raise ValueError(f\"shape_type={shape_type!r} is not supported.\")\n    return np.array(mask, dtype=bool)\n\n\ndef shapes_to_label(img_shape, shapes, label_name_to_value):\n    cls = np.zeros(img_shape[:2], dtype=np.int32)\n    ins = np.zeros_like(cls)\n    instances = []\n    for shape in shapes:\n        points = shape[\"points\"]\n        label = shape[\"label\"]\n        group_id = shape.get(\"group_id\")\n        if group_id is None:\n            group_id = uuid.uuid1()\n        shape_type = shape.get(\"shape_type\", None)\n\n        cls_name = label\n        instance = (cls_name, group_id)\n\n        if instance not in instances:\n            instances.append(instance)\n        ins_id = instances.index(instance) + 1\n        cls_id = label_name_to_value[cls_name]\n\n        mask: NDArray[np.bool_]\n        if shape_type == \"mask\":\n            if not isinstance(shape[\"mask\"], np.ndarray):\n                raise ValueError(\"shape['mask'] must be numpy.ndarray\")\n            mask = np.zeros(img_shape[:2], dtype=bool)\n            (x1, y1), (x2, y2) = np.asarray(points).astype(int)\n            mask[y1 : y2 + 1, x1 : x2 + 1] = shape[\"mask\"]\n        else:\n            mask = shape_to_mask(img_shape[:2], points, shape_type)\n\n        cls[mask] = cls_id\n        ins[mask] = ins_id\n\n    return cls, ins\n\n\ndef masks_to_bboxes(masks):\n    if masks.ndim != 3:\n        raise ValueError(f\"masks.ndim must be 3, but it is {masks.ndim}\")\n    if masks.dtype != bool:\n        raise ValueError(f\"masks.dtype must be bool type, but it is {masks.dtype}\")\n    bboxes = []\n    for mask in masks:\n        where = np.argwhere(mask)\n        (y1, x1), (y2, x2) = where.min(0), where.max(0) + 1\n        bboxes.append((y1, x1, y2, x2))\n    return np.asarray(bboxes, dtype=np.float32)\n"
  },
  {
    "path": "labelme/widgets/__init__.py",
    "content": "from ._ai_assisted_annotation_widget import AiAssistedAnnotationWidget\nfrom ._ai_text_to_annotation_widget import AiTextToAnnotationWidget\nfrom ._status import StatusStats\nfrom .brightness_contrast_dialog import BrightnessContrastDialog\nfrom .canvas import Canvas\nfrom .download import download_ai_model\nfrom .file_dialog_preview import FileDialogPreview\nfrom .label_dialog import LabelDialog\nfrom .label_dialog import LabelQLineEdit\nfrom .label_list_widget import LabelListWidget\nfrom .label_list_widget import LabelListWidgetItem\nfrom .tool_bar import ToolBar\nfrom .unique_label_qlist_widget import UniqueLabelQListWidget\nfrom .zoom_widget import ZoomWidget\n"
  },
  {
    "path": "labelme/widgets/_ai_assisted_annotation_widget.py",
    "content": "from collections.abc import Callable\n\nfrom loguru import logger\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\nfrom ._info_button import InfoButton\n\n\nclass AiAssistedAnnotationWidget(QtWidgets.QWidget):\n    _available_models: list[tuple[str, str]] = [\n        (\"efficientsam:10m\", \"EfficientSam (speed)\"),\n        (\"efficientsam:latest\", \"EfficientSam (accuracy)\"),\n        (\"sam:100m\", \"Sam (speed)\"),\n        (\"sam:300m\", \"Sam (balanced)\"),\n        (\"sam:latest\", \"Sam (accuracy)\"),\n        (\"sam2:small\", \"Sam2 (speed)\"),\n        (\"sam2:latest\", \"Sam2 (balanced)\"),\n        (\"sam2:large\", \"Sam2 (accuracy)\"),\n    ]\n\n    _model_combo: QtWidgets.QComboBox\n    _body: QtWidgets.QWidget\n\n    def __init__(\n        self,\n        default_model: str,\n        on_model_changed: Callable[[str], None],\n        parent: QtWidgets.QWidget | None = None,\n    ):\n        super().__init__(parent=parent)\n        self._init_ui(default_model=default_model, on_model_changed=on_model_changed)\n\n    def _init_ui(\n        self, default_model: str, on_model_changed: Callable[[str], None]\n    ) -> None:\n        layout = QtWidgets.QVBoxLayout()\n        layout.setContentsMargins(4, 4, 4, 4)\n        layout.setSpacing(2)\n        self.setLayout(layout)\n\n        header_layout = QtWidgets.QHBoxLayout()\n        header_layout.addStretch()\n        label = QtWidgets.QLabel(self.tr(\"AI-Assisted Annotation\"))\n        header_layout.addWidget(label)\n        info_button = InfoButton(\n            tooltip=self.tr(\n                \"AI suggests annotation in 'AI-Polygon' and 'AI-Mask' modes\"\n            )\n        )\n        header_layout.addWidget(info_button)\n        header_layout.addStretch()\n        layout.addLayout(header_layout)\n\n        self._body = body = QtWidgets.QWidget()\n        body.installEventFilter(self)\n        body_layout = QtWidgets.QVBoxLayout()\n        body_layout.setContentsMargins(0, 0, 0, 0)\n        body_layout.setSpacing(0)\n        body.setLayout(body_layout)\n\n        self._model_combo = QtWidgets.QComboBox()\n        for model_id, model_display in self._available_models:\n            self._model_combo.addItem(model_display, model_id)\n        body_layout.addWidget(self._model_combo)\n\n        layout.addWidget(body)\n\n        model_ui_names = [model_display for _, model_display in self._available_models]\n        if default_model in model_ui_names:\n            model_index = model_ui_names.index(default_model)\n        else:\n            logger.warning(\"Default AI model is not found: {!r}\", default_model)\n            model_index = 0\n\n        self._model_combo.currentIndexChanged.connect(\n            lambda index: on_model_changed(self._model_combo.itemData(index))\n        )\n        self._model_combo.setCurrentIndex(model_index)\n\n        self.setMaximumWidth(200)\n\n    def setEnabled(self, a0: bool) -> None:\n        self._body.setEnabled(a0)\n\n    def eventFilter(self, a0: QtCore.QObject, a1: QtCore.QEvent) -> bool:\n        if a0 == self._body and not self._body.isEnabled():\n            if a1.type() == QtCore.QEvent.Enter:\n                QtWidgets.QToolTip.showText(\n                    QtGui.QCursor.pos(),\n                    self.tr(\n                        \"Select 'AI-Polygon' or 'AI-Mask' mode \"\n                        \"to enable AI-Assisted Annotation\"\n                    ),\n                    self._body,\n                )\n        return super().eventFilter(a0, a1)\n"
  },
  {
    "path": "labelme/widgets/_ai_text_to_annotation_widget.py",
    "content": "from collections.abc import Callable\n\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\nfrom ._info_button import InfoButton\n\n\nclass AiTextToAnnotationWidget(QtWidgets.QWidget):\n    _available_models: list[tuple[str, str]] = [\n        (\"sam3:latest\", \"SAM3 (smart)\"),\n        (\"yoloworld:latest\", \"YOLO-World (fast)\"),\n    ]\n    _default_model_name: str = \"yoloworld:latest\"\n    _default_score_threshold: float = 0.1\n    _default_iou_threshold: float = 0.5\n\n    _text_input: QtWidgets.QLineEdit\n    _model_combo: QtWidgets.QComboBox\n    _score_spinbox: QtWidgets.QDoubleSpinBox\n    _iou_spinbox: QtWidgets.QDoubleSpinBox\n    _body: QtWidgets.QWidget\n\n    def __init__(self, on_submit, parent: QtWidgets.QWidget | None = None):\n        super().__init__(parent=parent)\n        self._init_ui(on_submit)\n\n    def _init_ui(self, on_submit: Callable[[], None]) -> None:\n        layout = QtWidgets.QVBoxLayout()\n        layout.setContentsMargins(4, 4, 4, 4)\n        layout.setSpacing(2)\n        self.setLayout(layout)\n\n        header_layout = QtWidgets.QHBoxLayout()\n        header_layout.addStretch()\n        label = QtWidgets.QLabel(self.tr(\"AI Text-to-Annotation\"))\n        header_layout.addWidget(label)\n        info_button = InfoButton(\n            tooltip=self.tr(\"AI creates annotations from the text prompt\")\n        )\n        header_layout.addWidget(info_button)\n        header_layout.addStretch()\n        layout.addLayout(header_layout)\n\n        self._body = body = QtWidgets.QWidget()\n        body.installEventFilter(self)\n        body_layout = QtWidgets.QVBoxLayout()\n        body_layout.setContentsMargins(0, 0, 0, 0)\n        body_layout.setSpacing(0)\n        body.setLayout(body_layout)\n\n        grid = QtWidgets.QGridLayout()\n        grid.setContentsMargins(0, 0, 0, 0)\n        grid.setSpacing(2)\n\n        text_input = QtWidgets.QLineEdit()\n        text_input.setPlaceholderText(self.tr(\"e.g., dog,cat,bird\"))\n        text_input.setFixedHeight(24)\n        grid.addWidget(text_input, 0, 0)\n        self._text_input = text_input\n\n        run_button = QtWidgets.QToolButton()\n        run_button.setText(self.tr(\"Run\"))\n        run_button.setFixedHeight(24)\n        run_button.setCursor(QtCore.Qt.PointingHandCursor)\n        run_button.clicked.connect(on_submit)\n        grid.addWidget(run_button, 0, 1)\n\n        settings_layout = QtWidgets.QHBoxLayout()\n        settings_layout.setContentsMargins(0, 0, 0, 0)\n        settings_layout.setSpacing(4)\n\n        self._model_combo = model_combo = QtWidgets.QComboBox()\n        for model_id, model_display in self._available_models:\n            model_combo.addItem(model_display, model_id)\n        model_index = next(\n            (\n                i\n                for i, (mid, _) in enumerate(self._available_models)\n                if mid == self._default_model_name\n            ),\n            0,\n        )\n        model_combo.setCurrentIndex(model_index)\n        settings_layout.addWidget(model_combo, stretch=1)\n\n        score_label = QtWidgets.QLabel(self.tr(\"Score\"))\n        score_label.setStyleSheet(\"color: gray; font-size: 10px;\")\n        settings_layout.addWidget(score_label)\n        #\n        self._score_spinbox = score_spinbox = QtWidgets.QDoubleSpinBox()\n        score_spinbox.setStyleSheet(\"font-size: 10px;\")\n        score_spinbox.setFixedWidth(50)\n        score_spinbox.setRange(0, 1)\n        score_spinbox.setSingleStep(0.05)\n        score_spinbox.setValue(self._default_score_threshold)\n        settings_layout.addWidget(score_spinbox)\n\n        iou_label = QtWidgets.QLabel(self.tr(\"IoU\"))\n        iou_label.setStyleSheet(\"color: gray; font-size: 10px;\")\n        settings_layout.addWidget(iou_label)\n        #\n        self._iou_spinbox = iou_spinbox = QtWidgets.QDoubleSpinBox()\n        iou_spinbox.setStyleSheet(\"font-size: 10px;\")\n        iou_spinbox.setFixedWidth(50)\n        iou_spinbox.setRange(0, 1)\n        iou_spinbox.setSingleStep(0.05)\n        iou_spinbox.setValue(self._default_iou_threshold)\n        settings_layout.addWidget(iou_spinbox)\n\n        grid.addLayout(settings_layout, 1, 0, 1, 2)\n\n        body_layout.addLayout(grid)\n        layout.addWidget(body)\n\n        self.setMaximumWidth(320)\n\n    def get_text_prompt(self) -> str:\n        return self._text_input.text()\n\n    def get_model_name(self) -> str:\n        return self._model_combo.currentData()\n\n    def get_score_threshold(self) -> float:\n        return self._score_spinbox.value()\n\n    def get_iou_threshold(self) -> float:\n        return self._iou_spinbox.value()\n\n    def setEnabled(self, a0: bool) -> None:\n        self._body.setEnabled(a0)\n\n    def eventFilter(self, a0: QtCore.QObject, a1: QtCore.QEvent) -> bool:\n        if a0 == self._body and not self._body.isEnabled():\n            if a1.type() == QtCore.QEvent.Enter:\n                QtWidgets.QToolTip.showText(\n                    QtGui.QCursor.pos(),\n                    self.tr(\n                        \"Select 'Polygon', 'Rectangle', 'AI-Polygon', or 'AI-Mask' \"\n                        \"mode to enable\"\n                    ),\n                    self._body,\n                )\n        return super().eventFilter(a0, a1)\n"
  },
  {
    "path": "labelme/widgets/_info_button.py",
    "content": "from PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\nfrom labelme.utils.qt import newIcon\n\n\nclass InfoButton(QtWidgets.QToolButton):\n    def __init__(self, tooltip: str, parent: QtWidgets.QWidget | None = None):\n        super().__init__(parent=parent)\n        self.setIcon(newIcon(\"info.svg\"))\n        self.setIconSize(QtCore.QSize(16, 16))\n        self.setStyleSheet(\n            \"\"\"\n            QToolButton {\n                border: none;\n                border-radius: 8px;\n                padding: 0px;\n            }\n            QToolButton:hover {\n                background-color: rgba(0, 0, 0, 0.1);\n            }\n            \"\"\"\n        )\n        self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))\n        self.setToolTip(tooltip)\n\n    def enterEvent(self, a0: QtCore.QEvent) -> None:\n        super().enterEvent(a0)\n        QtWidgets.QToolTip.showText(QtGui.QCursor.pos(), self.toolTip())\n"
  },
  {
    "path": "labelme/widgets/_status.py",
    "content": "from PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\n\nclass StatusStats(QtWidgets.QLabel):\n    def __init__(self):\n        super().__init__(\"\")\n\n        font = QtGui.QFont()\n        font.setFamily(\"monospace\")\n        font.setStyleHint(QtGui.QFont.Monospace)\n        self.setFont(font)\n"
  },
  {
    "path": "labelme/widgets/brightness_contrast_dialog.py",
    "content": "import PIL.Image\nimport PIL.ImageEnhance\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\nfrom PyQt5.QtGui import QImage\n\n\nclass BrightnessContrastDialog(QtWidgets.QDialog):\n    _base_value = 50\n\n    img: PIL.Image.Image\n\n    def __init__(self, img: PIL.Image.Image, callback, parent=None):\n        super().__init__(parent)\n        self.setModal(True)\n        self.setWindowTitle(\"Brightness/Contrast\")\n\n        sliders = {}\n        layouts = {}\n        for title in [\"Brightness:\", \"Contrast:\"]:\n            layout = QtWidgets.QHBoxLayout()\n            title_label = QtWidgets.QLabel(self.tr(title))\n            title_label.setFixedWidth(75)\n            layout.addWidget(title_label)\n            #\n            slider = QtWidgets.QSlider(Qt.Horizontal)\n            slider.setRange(0, 3 * self._base_value)\n            slider.setValue(self._base_value)\n            layout.addWidget(slider)\n            #\n            value_label = QtWidgets.QLabel(f\"{slider.value() / self._base_value:.2f}\")\n            value_label.setAlignment(Qt.AlignRight)\n            layout.addWidget(value_label)\n            #\n            slider.valueChanged.connect(self.onNewValue)\n            slider.valueChanged.connect(\n                lambda _,\n                value_label_=value_label,\n                slider_=slider: value_label_.setText(\n                    f\"{slider_.value() / self._base_value:.2f}\"\n                )\n            )\n            layouts[title] = layout\n            sliders[title] = slider\n\n        self.slider_brightness = sliders[\"Brightness:\"]\n        self.slider_contrast = sliders[\"Contrast:\"]\n        del sliders\n\n        v_layout = QtWidgets.QVBoxLayout()\n        v_layout.addLayout(layouts[\"Brightness:\"])\n        v_layout.addLayout(layouts[\"Contrast:\"])\n        del layouts\n        self.setLayout(v_layout)\n\n        self._alpha = None\n        if \"A\" in img.getbands():\n            self._alpha = img.getchannel(\"A\")\n        if img.mode != \"RGB\":\n            img = img.convert(\"RGB\")\n        self.img = img\n        self.callback = callback\n\n    def onNewValue(self, _):\n        brightness = self.slider_brightness.value() / self._base_value\n        contrast = self.slider_contrast.value() / self._base_value\n\n        img: PIL.Image.Image = self.img\n        if brightness != 1:\n            img = PIL.ImageEnhance.Brightness(img).enhance(brightness)\n        if contrast != 1:\n            img = PIL.ImageEnhance.Contrast(img).enhance(contrast)\n\n        fmt: QImage.Format\n        if self._alpha is None:\n            fmt = QImage.Format_RGB888\n        else:\n            img = img.convert(\"RGBA\")\n            img.putalpha(self._alpha)\n            fmt = QImage.Format_RGBA8888\n\n        qimage = QImage(\n            img.tobytes(), img.width, img.height, img.width * len(img.getbands()), fmt\n        )\n        self.callback(qimage)\n"
  },
  {
    "path": "labelme/widgets/canvas.py",
    "content": "from __future__ import annotations\n\nimport enum\nfrom typing import Literal\n\nimport imgviz\nimport numpy as np\nimport osam\nfrom loguru import logger\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import QPoint\nfrom PyQt5.QtCore import QPointF\nfrom PyQt5.QtCore import Qt\n\nimport labelme.utils\nfrom labelme._automation import OsamSession\nfrom labelme._automation import polygon_from_mask\nfrom labelme.shape import Shape\n\nfrom .download import download_ai_model\n\nCURSOR_DEFAULT = Qt.ArrowCursor\nCURSOR_POINT = Qt.PointingHandCursor\nCURSOR_DRAW = Qt.CrossCursor\nCURSOR_MOVE = Qt.ClosedHandCursor\nCURSOR_GRAB = Qt.OpenHandCursor\n\nMOVE_SPEED: float = 5.0\n\n\nclass CanvasMode(enum.Enum):\n    CREATE = enum.auto()\n    EDIT = enum.auto()\n\n\nclass Canvas(QtWidgets.QWidget):\n    pixmap: QtGui.QPixmap\n    _pixmap_hash: int | None\n    _cursor: QtCore.Qt.CursorShape\n    shapes: list[Shape]\n    shapesBackups: list[list[Shape]]\n    movingShape: bool\n    selectedShapes: list[Shape]\n    selectedShapesCopy: list[Shape]\n    current: Shape | None\n    hShape: Shape | None\n    _lasthShape: Shape | None\n    hVertex: int | None\n    _lasthVertex: int | None\n    hEdge: int | None\n    _lasthEdge: int | None\n\n    zoomRequest = QtCore.pyqtSignal(int, QPointF)\n    scrollRequest = QtCore.pyqtSignal(int, int)\n    newShape = QtCore.pyqtSignal()\n    selectionChanged = QtCore.pyqtSignal(list)\n    shapeMoved = QtCore.pyqtSignal()\n    drawingPolygon = QtCore.pyqtSignal(bool)\n    vertexSelected = QtCore.pyqtSignal(bool)\n    mouseMoved = QtCore.pyqtSignal(QPointF)\n    statusUpdated = QtCore.pyqtSignal(str)\n\n    mode: CanvasMode = CanvasMode.EDIT\n\n    # polygon, rectangle, line, or point\n    _createMode = \"polygon\"\n\n    _fill_drawing = False\n\n    prevPoint: QPointF\n    prevMovePoint: QPointF\n    offsets: tuple[QPointF, QPointF]\n\n    _dragging_start_pos: QPointF\n    _is_dragging: bool\n    _is_dragging_enabled: bool\n\n    _osam_session_model_name: str = \"sam2:latest\"\n    _osam_session: OsamSession | None\n\n    def __init__(self, *args, **kwargs):\n        self.epsilon: float = kwargs.pop(\"epsilon\", 10.0)\n        self.double_click = kwargs.pop(\"double_click\", \"close\")\n        if self.double_click not in [None, \"close\"]:\n            raise ValueError(\n                f\"Unexpected value for double_click event: {self.double_click}\"\n            )\n        self.num_backups = kwargs.pop(\"num_backups\", 10)\n        self._crosshair = kwargs.pop(\n            \"crosshair\",\n            {\n                \"polygon\": False,\n                \"rectangle\": True,\n                \"circle\": False,\n                \"line\": False,\n                \"point\": False,\n                \"linestrip\": False,\n                \"ai_polygon\": False,\n                \"ai_mask\": False,\n            },\n        )\n        super().__init__(*args, **kwargs)\n\n        self.resetState()\n\n        # self.line represents:\n        #   - createMode == 'polygon': edge from last point to current\n        #   - createMode == 'rectangle': diagonal line of the rectangle\n        #   - createMode == 'line': the line\n        #   - createMode == 'point': the point\n        self.line = Shape()\n        self.prevPoint = QPointF()\n        self.prevMovePoint = QPointF()\n        self.offsets = QPointF(), QPointF()\n        self.scale: float = 1.0\n        self._osam_session = None\n        self.visible: dict = {}\n        self._hideBackround: bool = False\n        self.hideBackround: bool = False\n        self.snapping = True\n        self.hShapeIsSelected: bool = False\n        self._painter = QtGui.QPainter()\n        self._dragging_start_pos = QPointF()\n        self._is_dragging = False\n        self._is_dragging_enabled = False\n        # Menus:\n        # 0: right-click without selection and dragging of shapes\n        # 1: right-click with selection and dragging of shapes\n        self.menus = (QtWidgets.QMenu(), QtWidgets.QMenu())\n        self.setMouseTracking(True)\n        self.setFocusPolicy(Qt.WheelFocus)\n\n    def fillDrawing(self):\n        return self._fill_drawing\n\n    def setFillDrawing(self, value):\n        self._fill_drawing = value\n\n    @property\n    def createMode(self):\n        return self._createMode\n\n    @createMode.setter\n    def createMode(self, value):\n        if value not in [\n            \"polygon\",\n            \"rectangle\",\n            \"circle\",\n            \"line\",\n            \"point\",\n            \"linestrip\",\n            \"ai_polygon\",\n            \"ai_mask\",\n        ]:\n            raise ValueError(f\"Unsupported createMode: {value}\")\n        self._createMode = value\n\n    def set_ai_model_name(self, model_name: str) -> None:\n        self._osam_session_model_name = model_name\n\n    def _get_osam_session(self) -> OsamSession:\n        if (\n            self._osam_session is None\n            or self._osam_session.model_name != self._osam_session_model_name\n        ):\n            self._osam_session = OsamSession(model_name=self._osam_session_model_name)\n        return self._osam_session\n\n    def _update_shape_with_ai(\n        self, points: list[QPointF], point_labels: list[int], shape: Shape\n    ) -> None:\n        image: np.ndarray = labelme.utils.img_qt_to_arr(img_qt=self.pixmap.toImage())\n        response: osam.types.GenerateResponse = self._get_osam_session().run(\n            image=imgviz.asrgb(image),\n            image_id=str(self._pixmap_hash),\n            points=np.array([[p.x(), p.y()] for p in points]),\n            point_labels=np.array(point_labels),\n        )\n        _update_shape_with_ai_response(\n            response=response,\n            shape=shape,\n            createMode=self.createMode,\n        )\n\n    def storeShapes(self):\n        shapesBackup = []\n        for shape in self.shapes:\n            shapesBackup.append(shape.copy())\n        if len(self.shapesBackups) > self.num_backups:\n            self.shapesBackups = self.shapesBackups[-self.num_backups - 1 :]\n        self.shapesBackups.append(shapesBackup)\n\n    @property\n    def isShapeRestorable(self):\n        # We save the state AFTER each edit (not before) so for an\n        # edit to be undoable, we expect the CURRENT and the PREVIOUS state\n        # to be in the undo stack.\n        if len(self.shapesBackups) < 2:\n            return False\n        return True\n\n    def restoreShape(self):\n        # This does _part_ of the job of restoring shapes.\n        # The complete process is also done in app.py::undoShapeEdit\n        # and app.py::loadShapes and our own Canvas::loadShapes function.\n        if not self.isShapeRestorable:\n            return\n        self.shapesBackups.pop()  # latest\n\n        # The application will eventually call Canvas.loadShapes which will\n        # push this right back onto the stack.\n        shapesBackup = self.shapesBackups.pop()\n        self.shapes = shapesBackup\n        self.selectedShapes = []\n        for shape in self.shapes:\n            shape.selected = False\n        self.update()\n\n    def enterEvent(self, a0: QtCore.QEvent) -> None:\n        self.overrideCursor(self._cursor)\n        self._update_status()\n\n    def leaveEvent(self, a0: QtCore.QEvent) -> None:\n        if self._set_highlight(hShape=None, hEdge=None, hVertex=None):\n            self.update()\n        self.restoreCursor()\n        self._update_status()\n\n    def focusOutEvent(self, a0: QtGui.QFocusEvent) -> None:\n        self.restoreCursor()\n        self._update_status()\n\n    def isVisible(self, shape: Shape) -> bool:  # type: ignore[override]\n        return self.visible.get(shape, True)\n\n    def drawing(self) -> bool:\n        return self.mode == CanvasMode.CREATE\n\n    def editing(self) -> bool:\n        return self.mode == CanvasMode.EDIT\n\n    def setEditing(self, value=True):\n        self.mode = CanvasMode.EDIT if value else CanvasMode.CREATE\n        if self.mode == CanvasMode.EDIT:\n            # CREATE -> EDIT\n            self.repaint()  # clear crosshair\n        else:\n            # EDIT -> CREATE\n            need_update: bool = self._set_highlight(\n                hShape=None, hEdge=None, hVertex=None\n            )\n            need_update |= self.deSelectShape()\n            if need_update:\n                self.update()\n\n    def _set_highlight(\n        self, hShape: Shape | None, hEdge: int | None, hVertex: int | None\n    ) -> bool:\n        need_update: bool = hShape is not None\n        if self.hShape:\n            self.hShape.highlightClear()\n            need_update = True\n        # NOTE: Store last highlighted for adding/removing points.\n        self._lasthShape = self.hShape if hShape is None else hShape\n        self._lasthVertex = self.hVertex if hVertex is None else hVertex\n        self._lasthEdge = self.hEdge if hEdge is None else hEdge\n        self.hShape = hShape\n        self.hVertex = hVertex\n        self.hEdge = hEdge\n        return need_update\n\n    def selectedVertex(self) -> bool:\n        return self.hVertex is not None\n\n    def selectedEdge(self) -> bool:\n        return self.hEdge is not None\n\n    def _update_status(self, extra_messages: list[str] | None = None) -> None:\n        messages: list[str] = []\n        if self.drawing():\n            messages.append(self.tr(\"Creating %r\") % self.createMode)\n            messages.append(self._get_create_mode_message())\n            if self.current:\n                messages.append(self.tr(\"ESC to cancel\"))\n            if self.canCloseShape():\n                messages.append(self.tr(\"Enter or Space to finalize\"))\n        else:\n            assert self.editing()\n            messages.append(self.tr(\"Editing shapes\"))\n        if extra_messages:\n            messages.extend(extra_messages)\n        self.statusUpdated.emit(\" • \".join(messages))\n\n    def _get_create_mode_message(self) -> str:\n        assert self.drawing()\n        isNew: bool = self.current is None\n        if self.createMode == \"ai_polygon\":\n            return self.tr(\n                \"Click points to include or Shift+Click to exclude for ai_polygon\"\n            )\n        if self.createMode == \"ai_mask\":\n            return self.tr(\n                \"Click points to include or Shift+Click to exclude for ai_mask\"\n            )\n        if self.createMode == \"line\":\n            if isNew:\n                return self.tr(\"Click start point for line\")\n            else:\n                return self.tr(\"Click end point for line\")\n        if self.createMode == \"linestrip\":\n            if isNew:\n                return self.tr(\"Click start point for linestrip\")\n            else:\n                return self.tr(\n                    \"Click next point or finish by Ctrl/Cmd+Click for linestrip\"\n                )\n        if self.createMode == \"circle\":\n            if isNew:\n                return self.tr(\"Click center point for circle\")\n            else:\n                return self.tr(\"Click point on circumference for circle\")\n        if self.createMode == \"rectangle\":\n            if isNew:\n                return self.tr(\"Click first corner for rectangle\")\n            else:\n                return self.tr(\"Click opposite corner for rectangle (Shift for square)\")\n        return self.tr(\"Click to add point\")\n\n    def mouseMoveEvent(self, a0: QtGui.QMouseEvent) -> None:\n        \"\"\"Update line with last point and current coordinates.\"\"\"\n        try:\n            pos = self.transformPos(a0.localPos())\n        except AttributeError:\n            return\n\n        self.mouseMoved.emit(pos)\n\n        self.prevMovePoint = pos\n\n        is_shift_pressed = a0.modifiers() & Qt.ShiftModifier\n\n        if self._is_dragging:\n            self.overrideCursor(CURSOR_GRAB)\n            delta: QPointF = pos - self._dragging_start_pos\n            self.scrollRequest.emit(int(delta.x()), Qt.Horizontal)\n            self.scrollRequest.emit(int(delta.y()), Qt.Vertical)\n            return\n\n        # Polygon drawing.\n        if self.drawing():\n            if self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n                self.line.shape_type = \"points\"\n            else:\n                self.line.shape_type = self.createMode\n\n            self.overrideCursor(CURSOR_DRAW)\n            if not self.current:\n                self.repaint()  # draw crosshair\n                self._update_status()\n                return\n\n            if self.outOfPixmap(pos):\n                # Don't allow the user to draw outside the pixmap.\n                # Project the point to the pixmap's edges.\n                pos = self.intersectionPoint(self.current[-1], pos)\n            elif (\n                self.snapping\n                and len(self.current) > 1\n                and self.createMode == \"polygon\"\n                and self.closeEnough(pos, self.current[0])\n            ):\n                # Attract line to starting point and\n                # colorise to alert the user.\n                pos = self.current[0]\n                self.overrideCursor(CURSOR_POINT)\n                self.current.highlightVertex(0, Shape.NEAR_VERTEX)\n            if self.createMode in [\"polygon\", \"linestrip\"]:\n                self.line.points = [self.current[-1], pos]\n                self.line.point_labels = [1, 1]\n            elif self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n                self.line.points = [self.current.points[-1], pos]\n                self.line.point_labels = [\n                    self.current.point_labels[-1],\n                    0 if is_shift_pressed else 1,\n                ]\n            elif self.createMode == \"rectangle\":\n                if is_shift_pressed:\n                    self.prevMovePoint = pos = _snap_cursor_pos_for_square(  # override\n                        pos=pos, opposite_vertex=self.current[0]\n                    )\n                self.line.points = [self.current[0], pos]\n                self.line.point_labels = [1, 1]\n                self.line.close()\n            elif self.createMode == \"circle\":\n                self.line.points = [self.current[0], pos]\n                self.line.point_labels = [1, 1]\n                self.line.shape_type = \"circle\"\n            elif self.createMode == \"line\":\n                self.line.points = [self.current[0], pos]\n                self.line.point_labels = [1, 1]\n                self.line.close()\n            elif self.createMode == \"point\":\n                self.line.points = [self.current[0]]\n                self.line.point_labels = [1]\n                self.line.close()\n            assert len(self.line.points) == len(self.line.point_labels)\n            self.repaint()\n            self.current.highlightClear()\n            self._update_status()\n            return\n\n        # Polygon copy moving.\n        if Qt.RightButton & a0.buttons():\n            if self.selectedShapesCopy and self.prevPoint is not None:\n                self.overrideCursor(CURSOR_MOVE)\n                self.boundedMoveShapes(self.selectedShapesCopy, pos)\n                self.repaint()\n            elif self.selectedShapes:\n                self.selectedShapesCopy = [s.copy() for s in self.selectedShapes]\n                self.repaint()\n            self._update_status()\n            return\n\n        # Polygon/Vertex moving.\n        if Qt.LeftButton & a0.buttons():\n            if self.selectedVertex():\n                self.boundedMoveVertex(pos, is_shift_pressed=is_shift_pressed)\n                self.repaint()\n                self.movingShape = True\n            elif self.selectedShapes and self.prevPoint is not None:\n                self.overrideCursor(CURSOR_MOVE)\n                self.boundedMoveShapes(self.selectedShapes, pos)\n                self.repaint()\n                self.movingShape = True\n            return\n\n        # Just hovering over the canvas, 2 possibilities:\n        # - Highlight shapes\n        # - Highlight vertex\n        # Update shape/vertex fill and tooltip value accordingly.\n        status_messages: list[str] = []\n        self._highlight_hover_shape(pos=pos, status_messages=status_messages)\n        self.vertexSelected.emit(self.hVertex is not None)\n        self._update_status(extra_messages=status_messages)\n\n    def _highlight_hover_shape(self, pos: QPointF, status_messages: list[str]) -> None:\n        ordered_shapes: list[Shape] = ([self.hShape] if self.hShape else []) + [\n            s for s in reversed(self.shapes) if self.isVisible(s) and s != self.hShape\n        ]\n\n        for shape in ordered_shapes:\n            index: int | None = shape.nearestVertex(pos, self.epsilon)\n            if index is not None:\n                self._set_highlight(hShape=shape, hEdge=None, hVertex=index)\n                shape.highlightVertex(index, shape.MOVE_VERTEX)\n                self.overrideCursor(CURSOR_POINT)\n                status_messages.append(self.tr(\"Click & drag to move point\"))\n                if shape.canRemovePoint():\n                    status_messages.append(\n                        self.tr(\"ALT + SHIFT + Click to delete point\")\n                    )\n                self.update()\n                return\n\n        for shape in ordered_shapes:\n            index_edge: int | None = shape.nearestEdge(pos, self.epsilon)\n            if index_edge is not None and shape.canAddPoint():\n                self._set_highlight(hShape=shape, hEdge=index_edge, hVertex=None)\n                self.overrideCursor(CURSOR_POINT)\n                status_messages.append(self.tr(\"ALT + Click to create point on shape\"))\n                self.update()\n                return\n\n        for shape in ordered_shapes:\n            if shape.containsPoint(pos):\n                self._set_highlight(hShape=shape, hEdge=None, hVertex=None)\n                status_messages.extend(\n                    [\n                        self.tr(\"Click & drag to move shape\"),\n                        self.tr(\"Right-click & drag to copy shape\"),\n                    ]\n                )\n                self.overrideCursor(CURSOR_GRAB)\n                self.update()\n                return\n\n        self.restoreCursor()\n        if self._set_highlight(hShape=None, hEdge=None, hVertex=None):\n            self.update()\n\n    def addPointToEdge(self):\n        shape = self._lasthShape\n        index = self._lasthEdge\n        point = self.prevMovePoint\n        if shape is None or index is None or point is None:\n            return\n        shape.insertPoint(index, point)\n        shape.highlightVertex(index, shape.MOVE_VERTEX)\n        self.hShape = shape\n        self.hVertex = index\n        self.hEdge = None\n        self.movingShape = True\n\n    def removeSelectedPoint(self):\n        shape = self._lasthShape\n        index = self._lasthVertex\n        if shape is None or index is None:\n            return\n        shape.removePoint(index)\n        shape.highlightClear()\n        self.hShape = shape\n        self._lasthVertex = None\n        self.movingShape = True  # Save changes\n\n    def mousePressEvent(self, a0: QtGui.QMouseEvent) -> None:\n        pos: QPointF = self.transformPos(a0.localPos())\n\n        is_shift_pressed = a0.modifiers() & Qt.ShiftModifier\n\n        if a0.button() == Qt.LeftButton:\n            if self.drawing():\n                if self.current:\n                    # Add point to existing shape.\n                    if self.createMode == \"polygon\":\n                        self.current.addPoint(self.line[1])\n                        self.line[0] = self.current[-1]\n                        if self.current.isClosed():\n                            self.finalise()\n                    elif self.createMode in [\"rectangle\", \"circle\", \"line\"]:\n                        assert len(self.current.points) == 1\n                        self.current.points = self.line.points\n                        self.finalise()\n                    elif self.createMode == \"linestrip\":\n                        self.current.addPoint(self.line[1])\n                        self.line[0] = self.current[-1]\n                        if int(a0.modifiers()) == Qt.ControlModifier:\n                            self.finalise()\n                    elif self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n                        self.current.addPoint(\n                            self.line.points[1],\n                            label=self.line.point_labels[1],\n                        )\n                        self.line.points[0] = self.current.points[-1]\n                        self.line.point_labels[0] = self.current.point_labels[-1]\n                        if a0.modifiers() & Qt.ControlModifier:\n                            self.finalise()\n                elif not self.outOfPixmap(pos):\n                    if self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n                        if not download_ai_model(\n                            model_name=self._osam_session_model_name, parent=self\n                        ):\n                            return\n\n                    # Create new shape.\n                    self.current = Shape(\n                        shape_type=\"points\"\n                        if self.createMode in [\"ai_polygon\", \"ai_mask\"]\n                        else self.createMode\n                    )\n                    self.current.addPoint(pos, label=0 if is_shift_pressed else 1)\n                    if self.createMode == \"point\":\n                        self.finalise()\n                    elif (\n                        self.createMode in [\"ai_polygon\", \"ai_mask\"]\n                        and a0.modifiers() & Qt.ControlModifier\n                    ):\n                        self.finalise()\n                    else:\n                        if self.createMode == \"circle\":\n                            self.current.shape_type = \"circle\"\n                        self.line.points = [pos, pos]\n                        if (\n                            self.createMode in [\"ai_polygon\", \"ai_mask\"]\n                            and is_shift_pressed\n                        ):\n                            self.line.point_labels = [0, 0]\n                        else:\n                            self.line.point_labels = [1, 1]\n                        self.setHiding()\n                        self.drawingPolygon.emit(True)\n                        self.update()\n            elif self.editing():\n                if self.selectedEdge() and a0.modifiers() == Qt.AltModifier:\n                    self.addPointToEdge()\n                elif self.selectedVertex() and a0.modifiers() == (\n                    Qt.AltModifier | Qt.ShiftModifier\n                ):\n                    self.removeSelectedPoint()\n\n                group_mode = int(a0.modifiers()) == Qt.ControlModifier\n                self.selectShapePoint(pos, multiple_selection_mode=group_mode)\n                self.prevPoint = pos\n                self.repaint()\n        elif a0.button() == Qt.RightButton and self.editing():\n            group_mode = int(a0.modifiers()) == Qt.ControlModifier\n            if not self.selectedShapes or (\n                self.hShape is not None and self.hShape not in self.selectedShapes\n            ):\n                self.selectShapePoint(pos, multiple_selection_mode=group_mode)\n                self.repaint()\n            self.prevPoint = pos\n        elif a0.button() == Qt.MiddleButton and self._is_dragging_enabled:\n            self.overrideCursor(CURSOR_GRAB)\n            self._dragging_start_pos = pos\n            self._is_dragging = True\n        self._update_status()\n\n    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent) -> None:\n        if a0.button() == Qt.RightButton:\n            menu = self.menus[len(self.selectedShapesCopy) > 0]\n            self.restoreCursor()\n            if not menu.exec_(self.mapToGlobal(a0.pos())) and self.selectedShapesCopy:  # type: ignore\n                # Cancel the move by deleting the shadow copy.\n                self.selectedShapesCopy = []\n                self.repaint()\n        elif a0.button() == Qt.LeftButton:\n            if self.editing():\n                if (\n                    self.hShape is not None\n                    and self.hShapeIsSelected\n                    and not self.movingShape\n                ):\n                    self.selectionChanged.emit(\n                        [x for x in self.selectedShapes if x != self.hShape]\n                    )\n        elif a0.button() == Qt.MiddleButton:\n            self._is_dragging = False\n            self.restoreCursor()\n\n        if self.movingShape and self.hShape and self.hShape in self.shapes:\n            index = self.shapes.index(self.hShape)\n            if self.shapesBackups[-1][index].points != self.shapes[index].points:\n                self.storeShapes()\n                self.shapeMoved.emit()\n\n            self.movingShape = False\n        self._update_status()\n\n    def endMove(self, copy):\n        assert self.selectedShapes and self.selectedShapesCopy\n        assert len(self.selectedShapesCopy) == len(self.selectedShapes)\n        if copy:\n            for i, shape in enumerate(self.selectedShapesCopy):\n                self.shapes.append(shape)\n                self.selectedShapes[i].selected = False\n                self.selectedShapes[i] = shape\n        else:\n            for i, shape in enumerate(self.selectedShapesCopy):\n                self.selectedShapes[i].points = shape.points\n        self.selectedShapesCopy = []\n        self.repaint()\n        self.storeShapes()\n        return True\n\n    def hideBackroundShapes(self, value):\n        self.hideBackround = value\n        if self.selectedShapes:\n            # Only hide other shapes if there is a current selection.\n            # Otherwise the user will not be able to select a shape.\n            self.setHiding(True)\n            self.update()\n\n    def setHiding(self, enable=True):\n        self._hideBackround = self.hideBackround if enable else False\n\n    def canCloseShape(self) -> bool:\n        if not self.drawing():\n            return False\n        if not self.current:\n            return False\n        if self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n            return True\n        if self.createMode == \"linestrip\":\n            return len(self.current) >= 2\n        return len(self.current) >= 3\n\n    def mouseDoubleClickEvent(self, a0: QtGui.QMouseEvent) -> None:\n        if self.double_click != \"close\":\n            return\n\n        if self.canCloseShape():\n            self.finalise()\n\n    def selectShapes(self, shapes):\n        self.setHiding()\n        self.selectionChanged.emit(shapes)\n        self.update()\n\n    def selectShapePoint(self, point, multiple_selection_mode):\n        \"\"\"Select the first shape created which contains this point.\"\"\"\n        if self.hVertex is not None:\n            assert self.hShape is not None\n            self.hShape.highlightVertex(i=self.hVertex, action=self.hShape.MOVE_VERTEX)\n        else:\n            shape: Shape\n            for shape in reversed(self.shapes):\n                if self.isVisible(shape) and shape.containsPoint(point):\n                    self.setHiding()\n                    if shape not in self.selectedShapes:\n                        if multiple_selection_mode:\n                            self.selectionChanged.emit(self.selectedShapes + [shape])\n                        else:\n                            self.selectionChanged.emit([shape])\n                        self.hShapeIsSelected = False\n                    else:\n                        self.hShapeIsSelected = True\n                    self.calculateOffsets(point)\n                    return\n        if self.deSelectShape():\n            self.update()\n\n    def calculateOffsets(self, point: QPointF) -> None:\n        left = self.pixmap.width() - 1\n        right = 0\n        top = self.pixmap.height() - 1\n        bottom = 0\n        for s in self.selectedShapes:\n            rect = s.boundingRect()\n            if rect.left() < left:\n                left = rect.left()\n            if rect.right() > right:\n                right = rect.right()\n            if rect.top() < top:\n                top = rect.top()\n            if rect.bottom() > bottom:\n                bottom = rect.bottom()\n\n        x1 = left - point.x()\n        y1 = top - point.y()\n        x2 = right - point.x()\n        y2 = bottom - point.y()\n        self.offsets = QPointF(x1, y1), QPointF(x2, y2)\n\n    def boundedMoveVertex(self, pos: QPointF, is_shift_pressed: bool) -> None:\n        if self.hVertex is None:\n            logger.warning(\"hVertex is None, so cannot move vertex: pos={!r}\", pos)\n            return\n        assert self.hShape is not None\n\n        if self.hVertex >= len(self.hShape.points):\n            logger.warning(\n                \"hVertex is out of range: hVertex={:d}, len(points)={:d}\",\n                self.hVertex,\n                len(self.hShape.points),\n            )\n            return\n\n        if self.outOfPixmap(pos):\n            pos = self.intersectionPoint(self.hShape[self.hVertex], pos)\n\n        if is_shift_pressed and self.hShape.shape_type == \"rectangle\":\n            pos = _snap_cursor_pos_for_square(\n                pos=pos, opposite_vertex=self.hShape[1 - self.hVertex]\n            )\n\n        self.hShape.moveVertex(i=self.hVertex, pos=pos)\n\n    def boundedMoveShapes(self, shapes, pos):\n        if self.outOfPixmap(pos):\n            return False  # No need to move\n        o1 = pos + self.offsets[0]\n        if self.outOfPixmap(o1):\n            pos -= QPointF(min(0, o1.x()), min(0, o1.y()))\n        o2 = pos + self.offsets[1]\n        if self.outOfPixmap(o2):\n            pos += QPointF(\n                min(0, self.pixmap.width() - o2.x()),\n                min(0, self.pixmap.height() - o2.y()),\n            )\n        # XXX: The next line tracks the new position of the cursor\n        # relative to the shape, but also results in making it\n        # a bit \"shaky\" when nearing the border and allows it to\n        # go outside of the shape's area for some reason.\n        # self.calculateOffsets(self.selectedShapes, pos)\n        dp = pos - self.prevPoint\n        if dp:\n            for shape in shapes:\n                shape.moveBy(dp)\n            self.prevPoint = pos\n            return True\n        return False\n\n    def deSelectShape(self) -> bool:\n        need_update: bool = False\n        if self.selectedShapes:\n            self.setHiding(False)\n            self.selectionChanged.emit([])\n            self.hShapeIsSelected = False\n            need_update = True\n        return need_update\n\n    def deleteSelected(self):\n        deleted_shapes = []\n        if self.selectedShapes:\n            for shape in self.selectedShapes:\n                self.shapes.remove(shape)\n                deleted_shapes.append(shape)\n            self.storeShapes()\n            self.selectedShapes = []\n            self.update()\n        return deleted_shapes\n\n    def deleteShape(self, shape):\n        if shape in self.selectedShapes:\n            self.selectedShapes.remove(shape)\n        if shape in self.shapes:\n            self.shapes.remove(shape)\n        self.storeShapes()\n        self.update()\n\n    def paintEvent(self, a0: QtGui.QPaintEvent) -> None:\n        if not self.pixmap:\n            return super().paintEvent(a0)\n\n        p = self._painter\n        p.begin(self)\n        p.setRenderHint(QtGui.QPainter.Antialiasing)\n        p.setRenderHint(QtGui.QPainter.HighQualityAntialiasing)\n        p.setRenderHint(QtGui.QPainter.SmoothPixmapTransform)\n\n        p.scale(self.scale, self.scale)\n        p.translate(self.offsetToCenter())\n\n        p.drawPixmap(0, 0, self.pixmap)\n\n        p.scale(1 / self.scale, 1 / self.scale)\n\n        # draw crosshair\n        if (\n            self._crosshair[self._createMode]\n            and self.drawing()\n            and self.prevMovePoint is not None\n            and not self.outOfPixmap(self.prevMovePoint)\n        ):\n            p.setPen(QtGui.QColor(0, 0, 0))\n            p.drawLine(\n                0,\n                int(self.prevMovePoint.y() * self.scale),\n                int(self.pixmap.width() * self.scale) - 1,\n                int(self.prevMovePoint.y() * self.scale),\n            )\n            p.drawLine(\n                int(self.prevMovePoint.x() * self.scale),\n                0,\n                int(self.prevMovePoint.x() * self.scale),\n                int(self.pixmap.height() * self.scale) - 1,\n            )\n\n        Shape.scale = self.scale\n        for shape in self.shapes:\n            if (shape.selected or not self._hideBackround) and self.isVisible(shape):\n                shape.fill = shape.selected or shape == self.hShape\n                shape.paint(p)\n        if self.current:\n            self.current.paint(p)\n            assert len(self.line.points) == len(self.line.point_labels)\n            self.line.paint(p)\n        if self.selectedShapesCopy:\n            for s in self.selectedShapesCopy:\n                s.paint(p)\n\n        if not self.current or self.createMode not in [\n            \"polygon\",\n            \"ai_polygon\",\n            \"ai_mask\",\n        ]:\n            p.end()\n            return\n\n        drawing_shape: Shape = self.current.copy()\n        if self.createMode == \"polygon\":\n            if self.fillDrawing() and len(self.current.points) >= 2:\n                assert drawing_shape.fill_color is not None\n                if drawing_shape.fill_color.getRgb()[3] == 0:\n                    logger.warning(\n                        \"fill_drawing=true, but fill_color is transparent,\"\n                        \" so forcing to be opaque.\"\n                    )\n                    drawing_shape.fill_color.setAlpha(64)\n                drawing_shape.addPoint(self.line[1])\n        elif self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n            drawing_shape.addPoint(\n                point=self.line.points[1],\n                label=self.line.point_labels[1],\n            )\n            self._update_shape_with_ai(\n                points=drawing_shape.points,\n                point_labels=drawing_shape.point_labels,\n                shape=drawing_shape,\n            )\n        drawing_shape.fill = self.fillDrawing()\n        drawing_shape.selected = self.fillDrawing()\n        drawing_shape.paint(p)\n        p.end()\n\n    def transformPos(self, point: QPointF) -> QPointF:\n        \"\"\"Convert from widget-logical coordinates to painter-logical ones.\"\"\"\n        return point / self.scale - self.offsetToCenter()\n\n    def enableDragging(self, enabled: bool):\n        self._is_dragging_enabled = enabled\n\n    def offsetToCenter(self) -> QPointF:\n        s = self.scale\n        area = super().size()\n        w, h = self.pixmap.width() * s, self.pixmap.height() * s\n        aw, ah = area.width(), area.height()\n        x = (aw - w) / (2 * s) if aw > w else 0\n        y = (ah - h) / (2 * s) if ah > h else 0\n        return QPointF(x, y)\n\n    def outOfPixmap(self, p: QPointF) -> bool:\n        w, h = self.pixmap.width(), self.pixmap.height()\n        return not (0 <= p.x() <= w and 0 <= p.y() <= h)\n\n    def finalise(self):\n        assert self.current\n        if self.createMode in [\"ai_polygon\", \"ai_mask\"]:\n            self._update_shape_with_ai(\n                points=self.current.points,\n                point_labels=self.current.point_labels,\n                shape=self.current,\n            )\n        self.current.close()\n\n        self.shapes.append(self.current)\n        self.storeShapes()\n        self.current = None\n        self.setHiding(False)\n        self.newShape.emit()\n        self.update()\n\n    def closeEnough(self, p1, p2):\n        # d = distance(p1 - p2)\n        # m = (p1-p2).manhattanLength()\n        # print \"d %.2f, m %d, %.2f\" % (d, m, d - m)\n        # divide by scale to allow more precision when zoomed in\n        return labelme.utils.distance(p1 - p2) < (self.epsilon / self.scale)\n\n    def intersectionPoint(self, p1: QPointF, p2: QPointF) -> QPointF:\n        # Cycle through each image edge in clockwise fashion,\n        # and find the one intersecting the current line segment.\n        # http://paulbourke.net/geometry/lineline2d/\n        size = self.pixmap.size()\n        points = [\n            (0, 0),\n            (size.width(), 0),\n            (size.width(), size.height()),\n            (0, size.height()),\n        ]\n        # x1, y1 should be in the pixmap, x2, y2 should be out of the pixmap\n        x1 = min(max(p1.x(), 0), size.width())\n        y1 = min(max(p1.y(), 0), size.height())\n        x2, y2 = p2.x(), p2.y()\n        d, i, (x, y) = min(self.intersectingEdges((x1, y1), (x2, y2), points))\n        x3, y3 = points[i]\n        x4, y4 = points[(i + 1) % 4]\n        if (x, y) == (x1, y1):\n            # Handle cases where previous point is on one of the edges.\n            if x3 == x4:\n                return QPointF(x3, min(max(0, y2), max(y3, y4)))\n            else:  # y3 == y4\n                return QPointF(min(max(0, x2), max(x3, x4)), y3)\n        return QPointF(x, y)\n\n    def intersectingEdges(self, point1, point2, points):\n        \"\"\"Find intersecting edges.\n\n        For each edge formed by `points', yield the intersection\n        with the line segment `(x1,y1) - (x2,y2)`, if it exists.\n        Also return the distance of `(x2,y2)' to the middle of the\n        edge along with its index, so that the one closest can be chosen.\n        \"\"\"\n        (x1, y1) = point1\n        (x2, y2) = point2\n        for i in range(4):\n            x3, y3 = points[i]\n            x4, y4 = points[(i + 1) % 4]\n            denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)\n            nua = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)\n            nub = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)\n            if denom == 0:\n                # This covers two cases:\n                #   nua == nub == 0: Coincident\n                #   otherwise: Parallel\n                continue\n            ua, ub = nua / denom, nub / denom\n            if 0 <= ua <= 1 and 0 <= ub <= 1:\n                x = x1 + ua * (x2 - x1)\n                y = y1 + ua * (y2 - y1)\n                m = QPointF((x3 + x4) / 2, (y3 + y4) / 2)\n                d = labelme.utils.distance(m - QPointF(x2, y2))\n                yield d, i, (x, y)\n\n    # These two, along with a call to adjustSize are required for the\n    # scroll area.\n    def sizeHint(self):\n        return self.minimumSizeHint()\n\n    def minimumSizeHint(self):\n        if not self.pixmap:\n            return super().minimumSizeHint()\n\n        min_size = self.scale * self.pixmap.size()\n        if self._is_dragging_enabled:\n            # When drag buffer should be enabled, add a bit of buffer around the image\n            # This lets dragging the image around have a bit of give on the edges\n            min_size = 1.167 * min_size\n        return min_size\n\n    def wheelEvent(self, a0: QtGui.QWheelEvent) -> None:\n        mods: Qt.KeyboardModifiers = a0.modifiers()\n        delta: QPoint = a0.angleDelta()\n        if Qt.ControlModifier == int(mods):\n            # with Ctrl/Command key\n            # zoom\n            self.zoomRequest.emit(delta.y(), a0.posF())\n        else:\n            # scroll\n            self.scrollRequest.emit(delta.x(), Qt.Horizontal)\n            self.scrollRequest.emit(delta.y(), Qt.Vertical)\n        a0.accept()\n\n    def moveByKeyboard(self, offset):\n        if self.selectedShapes:\n            self.boundedMoveShapes(self.selectedShapes, self.prevPoint + offset)\n            self.repaint()\n            self.movingShape = True\n\n    def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:\n        modifiers = a0.modifiers()\n        key = a0.key()\n        if self.drawing():\n            if key == Qt.Key_Escape and self.current:\n                self.current = None\n                self.drawingPolygon.emit(False)\n                self.update()\n            elif (\n                key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Space)\n                and self.canCloseShape()\n            ):\n                self.finalise()\n            elif modifiers == Qt.AltModifier:\n                self.snapping = False\n        elif self.editing():\n            if key == Qt.Key_Up:\n                self.moveByKeyboard(QPointF(0.0, -MOVE_SPEED))\n            elif key == Qt.Key_Down:\n                self.moveByKeyboard(QPointF(0.0, MOVE_SPEED))\n            elif key == Qt.Key_Left:\n                self.moveByKeyboard(QPointF(-MOVE_SPEED, 0.0))\n            elif key == Qt.Key_Right:\n                self.moveByKeyboard(QPointF(MOVE_SPEED, 0.0))\n        self._update_status()\n\n    def keyReleaseEvent(self, a0: QtGui.QKeyEvent) -> None:\n        modifiers = a0.modifiers()\n        if self.drawing():\n            if int(modifiers) == 0:\n                self.snapping = True\n        elif self.editing():\n            if (\n                self.movingShape\n                and self.selectedShapes\n                and self.selectedShapes[0] in self.shapes\n            ):\n                index = self.shapes.index(self.selectedShapes[0])\n                if self.shapesBackups[-1][index].points != self.shapes[index].points:\n                    self.storeShapes()\n                    self.shapeMoved.emit()\n\n                self.movingShape = False\n\n    def setLastLabel(self, text, flags):\n        assert text\n        self.shapes[-1].label = text\n        self.shapes[-1].flags = flags\n        self.shapesBackups.pop()\n        self.storeShapes()\n        return self.shapes[-1]\n\n    def undoLastLine(self):\n        assert self.shapes\n        self.current = self.shapes.pop()\n        self.current.setOpen()\n        self.current.restoreShapeRaw()\n        if self.createMode in [\"polygon\", \"linestrip\"]:\n            self.line.points = [self.current[-1], self.current[0]]\n        elif self.createMode in [\"rectangle\", \"line\", \"circle\"]:\n            self.current.points = self.current.points[0:1]\n        elif self.createMode == \"point\":\n            self.current = None\n        self.drawingPolygon.emit(True)\n\n    def undoLastPoint(self):\n        if not self.current or self.current.isClosed():\n            return\n        self.current.popPoint()\n        if len(self.current) > 0:\n            self.line[0] = self.current[-1]\n        else:\n            self.current = None\n            self.drawingPolygon.emit(False)\n        self.update()\n\n    def loadPixmap(self, pixmap, clear_shapes=True):\n        self.pixmap = pixmap\n        self._pixmap_hash = hash(\n            labelme.utils.img_qt_to_arr(img_qt=self.pixmap.toImage()).tobytes()\n        )\n        if clear_shapes:\n            self.shapes = []\n        self.update()\n\n    def loadShapes(self, shapes, replace=True):\n        if replace:\n            self.shapes = list(shapes)\n        else:\n            self.shapes.extend(shapes)\n        self.storeShapes()\n        self.current = None\n        self.hShape = None\n        self.hVertex = None\n        self.hEdge = None\n        self.update()\n\n    def setShapeVisible(self, shape, value):\n        self.visible[shape] = value\n        self.update()\n\n    def overrideCursor(self, cursor):\n        if cursor == self._cursor:\n            return\n        self.restoreCursor()\n        self._cursor = cursor\n        QtWidgets.QApplication.setOverrideCursor(cursor)\n\n    def restoreCursor(self):\n        self._cursor = CURSOR_DEFAULT\n        QtWidgets.QApplication.restoreOverrideCursor()\n\n    def resetState(self):\n        self.restoreCursor()\n        self.pixmap = QtGui.QPixmap()\n        self._pixmap_hash = None\n        self.shapes = []\n        self.shapesBackups = []\n        self.movingShape = False\n        self.selectedShapes = []\n        self.selectedShapesCopy = []\n        self.current = None\n        self.hShape = None\n        self._lasthShape = None\n        self.hVertex = None\n        self._lasthVertex = None\n        self.hEdge = None\n        self._lasthEdge = None\n        self.update()\n\n\ndef _update_shape_with_ai_response(\n    response: osam.types.GenerateResponse,\n    shape: Shape,\n    createMode: Literal[\"ai_polygon\", \"ai_mask\"],\n) -> None:\n    if createMode not in [\"ai_polygon\", \"ai_mask\"]:\n        raise ValueError(\n            f\"createMode must be 'ai_polygon' or 'ai_mask', not {createMode}\"\n        )\n\n    if not response.annotations:\n        logger.warning(\"No annotations returned\")\n        return\n\n    if createMode == \"ai_mask\":\n        y1: int\n        x1: int\n        y2: int\n        x2: int\n        if response.annotations[0].bounding_box is None:\n            y1, x1, y2, x2 = imgviz.masks_to_bboxes(\n                masks=[response.annotations[0].mask]\n            )[0].astype(int)\n        else:\n            y1 = response.annotations[0].bounding_box.ymin\n            x1 = response.annotations[0].bounding_box.xmin\n            y2 = response.annotations[0].bounding_box.ymax\n            x2 = response.annotations[0].bounding_box.xmax\n        shape.setShapeRefined(\n            shape_type=\"mask\",\n            points=[QPointF(x1, y1), QPointF(x2, y2)],\n            point_labels=[1, 1],\n            mask=response.annotations[0].mask[y1 : y2 + 1, x1 : x2 + 1],\n        )\n    elif createMode == \"ai_polygon\":\n        points = polygon_from_mask.compute_polygon_from_mask(\n            mask=response.annotations[0].mask\n        )\n        if len(points) < 2:\n            return\n        shape.setShapeRefined(\n            shape_type=\"polygon\",\n            points=[QPointF(point[0], point[1]) for point in points],\n            point_labels=[1] * len(points),\n        )\n\n\ndef _snap_cursor_pos_for_square(pos: QPointF, opposite_vertex: QPointF) -> QPointF:\n    pos_from_opposite: QPointF = pos - opposite_vertex\n    square_size: float = min(abs(pos_from_opposite.x()), abs(pos_from_opposite.y()))\n    return opposite_vertex + QPointF(\n        np.sign(pos_from_opposite.x()) * square_size,\n        np.sign(pos_from_opposite.y()) * square_size,\n    )\n"
  },
  {
    "path": "labelme/widgets/download.py",
    "content": "from __future__ import annotations\n\nimport types\n\nimport osam\nfrom loguru import logger\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import QObject\nfrom PyQt5.QtCore import QRunnable\nfrom PyQt5.QtCore import Qt\nfrom PyQt5.QtCore import QThreadPool\nfrom PyQt5.QtCore import pyqtSignal\nfrom PyQt5.QtWidgets import QProgressDialog\n\n\nclass _AiModelDownloadSignals(QObject):\n    finished = pyqtSignal()\n    error = pyqtSignal(Exception)\n\n\nclass _AiModelDownloadWorker(QRunnable):\n    def __init__(self, model_type, signals: _AiModelDownloadSignals):\n        super().__init__()\n        self.model_type = model_type\n        self.signals = signals\n\n    def run(self):\n        try:\n            self.model_type.pull()\n            self.signals.finished.emit()\n        except Exception as e:\n            self.signals.error.emit(e)\n\n\ndef download_ai_model(model_name: str, parent: QtWidgets.QWidget) -> bool:\n    model_type = osam.apis.get_model_type_by_name(model_name)\n\n    if _is_already_downloaded := model_type.get_size() is not None:\n        return True\n\n    dialog: QProgressDialog = QProgressDialog(\n        \"Downloading AI model...\\n(requires internet connection)\",\n        None,  # type: ignore\n        0,\n        0,\n        parent,\n    )  # type: ignore[call-overload]\n    dialog.setWindowModality(Qt.WindowModal)\n    dialog.setMinimumDuration(0)\n\n    signals: _AiModelDownloadSignals = _AiModelDownloadSignals()\n    worker: _AiModelDownloadWorker = _AiModelDownloadWorker(model_type, signals)\n    pool = QThreadPool.globalInstance()\n\n    handle_error_attrs = types.SimpleNamespace(e=None)\n\n    def handle_error(e: Exception):\n        logger.error(\"Exception occurred: {}\", e)\n        handle_error_attrs.e = e\n        #\n        QtWidgets.QApplication.setOverrideCursor(Qt.ArrowCursor)\n        dialog.setRange(0, 1)  # pause busy mode\n        dialog.setLabelText(\"Failed to download AI model.\\n(check internet connection)\")\n        dialog.setCancelButtonText(\"Close\")\n\n    signals.finished.connect(dialog.close)\n    signals.error.connect(handle_error)\n\n    dialog.show()\n    pool.start(worker)\n    dialog.exec_()\n\n    return handle_error_attrs.e is None\n"
  },
  {
    "path": "labelme/widgets/file_dialog_preview.py",
    "content": "import json\nfrom typing import cast\n\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\n\nclass ScrollAreaPreview(QtWidgets.QScrollArea):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        self.setWidgetResizable(True)\n\n        content = QtWidgets.QWidget(self)\n        self.setWidget(content)\n\n        lay = QtWidgets.QVBoxLayout(content)\n\n        self.label = QtWidgets.QLabel(content)\n        self.label.setWordWrap(True)\n\n        lay.addWidget(self.label)\n\n    def setText(self, text):\n        self.label.setText(text)\n\n    def setPixmap(self, pixmap):\n        self.label.setPixmap(pixmap)\n\n    def clear(self):\n        self.label.clear()\n\n\nclass FileDialogPreview(QtWidgets.QFileDialog):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.setOption(self.DontUseNativeDialog, True)\n\n        self.labelPreview = ScrollAreaPreview(self)\n        self.labelPreview.setFixedSize(300, 300)\n        self.labelPreview.setHidden(True)\n\n        box = QtWidgets.QVBoxLayout()\n        box.addWidget(self.labelPreview)\n        box.addStretch()\n\n        self.setFixedSize(self.width() + 300, self.height())\n        layout = self.layout()\n        layout = cast(QtWidgets.QGridLayout, layout)\n        layout.addLayout(box, 1, 3, 1, 1)\n        self.currentChanged.connect(self.onChange)\n\n    def onChange(self, path):\n        if path.lower().endswith(\".json\"):\n            with open(path) as f:\n                data = json.load(f)\n                self.labelPreview.setText(json.dumps(data, indent=4, sort_keys=False))\n            self.labelPreview.label.setAlignment(\n                QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop\n            )\n            self.labelPreview.setHidden(False)\n        else:\n            pixmap = QtGui.QPixmap(path)\n            if pixmap.isNull():\n                self.labelPreview.clear()\n                self.labelPreview.setHidden(True)\n            else:\n                self.labelPreview.setPixmap(\n                    pixmap.scaled(\n                        self.labelPreview.width() - 30,\n                        self.labelPreview.height() - 30,\n                        QtCore.Qt.KeepAspectRatio,\n                        QtCore.Qt.SmoothTransformation,\n                    )\n                )\n                self.labelPreview.label.setAlignment(QtCore.Qt.AlignCenter)\n                self.labelPreview.setHidden(False)\n"
  },
  {
    "path": "labelme/widgets/label_dialog.py",
    "content": "import re\nfrom typing import cast\n\nfrom loguru import logger\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\nimport labelme.utils\n\n# TODO(unknown):\n# - Calculate optimal position so as not to go out of screen area.\n\n\nclass LabelQLineEdit(QtWidgets.QLineEdit):\n    def setListWidget(self, list_widget):\n        self.list_widget = list_widget\n\n    def keyPressEvent(self, a0: QtGui.QKeyEvent) -> None:\n        if a0.key() in [QtCore.Qt.Key_Up, QtCore.Qt.Key_Down]:\n            self.list_widget.keyPressEvent(a0)\n        else:\n            super().keyPressEvent(a0)\n\n\nclass LabelDialog(QtWidgets.QDialog):\n    def __init__(\n        self,\n        text=\"Enter object label\",\n        parent=None,\n        labels=None,\n        sort_labels=True,\n        show_text_field=True,\n        completion=\"startswith\",\n        fit_to_content=None,\n        flags=None,\n    ):\n        if fit_to_content is None:\n            fit_to_content = {\"row\": False, \"column\": True}\n        self._fit_to_content = fit_to_content\n\n        super().__init__(parent)\n        self.edit = LabelQLineEdit()\n        self.edit.setPlaceholderText(text)\n        self.edit.setValidator(labelme.utils.labelValidator())\n        self.edit.editingFinished.connect(self.postProcess)\n        if flags:\n            self.edit.textChanged.connect(self.updateFlags)\n        self.edit_group_id = QtWidgets.QLineEdit()\n        self.edit_group_id.setPlaceholderText(\"Group ID\")\n        self.edit_group_id.setValidator(\n            QtGui.QRegExpValidator(QtCore.QRegExp(r\"\\d*\"), None)\n        )\n        layout = QtWidgets.QVBoxLayout()\n        if show_text_field:\n            layout_edit = QtWidgets.QHBoxLayout()\n            layout_edit.addWidget(self.edit, 6)\n            layout_edit.addWidget(self.edit_group_id, 2)\n            layout.addLayout(layout_edit)\n        # buttons\n        self.buttonBox = bb = QtWidgets.QDialogButtonBox(\n            QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel,\n            QtCore.Qt.Horizontal,\n            self,\n        )\n        bb.accepted.connect(self.validate)\n        bb.rejected.connect(self.reject)\n        layout.addWidget(bb)\n        # label_list\n        self.labelList = QtWidgets.QListWidget()\n        if self._fit_to_content[\"row\"]:\n            self.labelList.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)\n        if self._fit_to_content[\"column\"]:\n            self.labelList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)\n        self._sort_labels = sort_labels\n        if labels:\n            self.labelList.addItems(labels)\n        if self._sort_labels:\n            self.labelList.sortItems()\n        else:\n            self.labelList.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)\n        self.labelList.currentItemChanged.connect(self.labelSelected)\n        self.labelList.itemDoubleClicked.connect(self.labelDoubleClicked)\n        self.labelList.setFixedHeight(150)\n        self.edit.setListWidget(self.labelList)\n        layout.addWidget(self.labelList)\n        # label_flags\n        if flags is None:\n            flags = {}\n        self._flags = flags\n        self.flagsLayout = QtWidgets.QVBoxLayout()\n        self.resetFlags()\n        layout.addItem(self.flagsLayout)\n        self.edit.textChanged.connect(self.updateFlags)\n        # text edit\n        self.editDescription = QtWidgets.QTextEdit()\n        self.editDescription.setPlaceholderText(\"Label description\")\n        self.editDescription.setFixedHeight(50)\n        layout.addWidget(self.editDescription)\n        self.setLayout(layout)\n        # completion\n        completer = QtWidgets.QCompleter()\n        if completion == \"startswith\":\n            completer.setCompletionMode(QtWidgets.QCompleter.InlineCompletion)\n            # Default settings.\n            # completer.setFilterMode(QtCore.Qt.MatchStartsWith)\n        elif completion == \"contains\":\n            completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)\n            completer.setFilterMode(QtCore.Qt.MatchContains)\n        else:\n            raise ValueError(f\"Unsupported completion: {completion}\")\n        completer.setModel(self.labelList.model())\n        self.edit.setCompleter(completer)\n\n    def addLabelHistory(self, label):\n        if self.labelList.findItems(label, QtCore.Qt.MatchExactly):\n            return\n        self.labelList.addItem(label)\n        if self._sort_labels:\n            self.labelList.sortItems()\n\n    def labelSelected(self, item):\n        self.edit.setText(item.text())\n\n    def validate(self):\n        if not self.edit.isEnabled():\n            self.accept()\n            return\n\n        if self._get_stripped_text():\n            self.accept()\n\n    def _get_stripped_text(self) -> str:\n        text = self.edit.text()\n        if hasattr(text, \"strip\"):\n            return str(text.strip())\n        if hasattr(text, \"trimmed\"):\n            return str(text.trimmed())\n        return str(text)\n\n    def labelDoubleClicked(self, item):\n        self.validate()\n\n    def postProcess(self):\n        self.edit.setText(self._get_stripped_text())\n\n    def updateFlags(self, label_new):\n        # keep state of shared flags\n        flags_old = self.getFlags()\n\n        flags_new = {}\n        for pattern, keys in self._flags.items():\n            if re.match(pattern, label_new):\n                for key in keys:\n                    flags_new[key] = flags_old.get(key, False)\n        self.setFlags(flags_new)\n\n    def deleteFlags(self):\n        for i in reversed(range(self.flagsLayout.count())):\n            item = self.flagsLayout.itemAt(i).widget()\n            self.flagsLayout.removeWidget(item)\n            item.setParent(QtWidgets.QWidget())\n\n    def resetFlags(self, label=\"\"):\n        flags = {}\n        for pattern, keys in self._flags.items():\n            if re.match(pattern, label):\n                for key in keys:\n                    flags[key] = False\n        self.setFlags(flags)\n\n    def setFlags(self, flags):\n        self.deleteFlags()\n        for key in flags:\n            item = QtWidgets.QCheckBox(key, self)\n            item.setChecked(flags[key])\n            self.flagsLayout.addWidget(item)\n            item.show()\n\n    def getFlags(self):\n        flags = {}\n        for i in range(self.flagsLayout.count()):\n            item = self.flagsLayout.itemAt(i).widget()\n            item = cast(QtWidgets.QCheckBox, item)\n            flags[item.text()] = item.isChecked()\n        return flags\n\n    def getGroupId(self):\n        group_id = self.edit_group_id.text()\n        if group_id:\n            return int(group_id)\n        return None\n\n    def popUp(\n        self,\n        text=None,\n        move=True,\n        flags=None,\n        group_id=None,\n        description=None,\n        flags_disabled: bool = False,\n    ):\n        if self._fit_to_content[\"row\"]:\n            self.labelList.setMinimumHeight(\n                self.labelList.sizeHintForRow(0) * self.labelList.count() + 2\n            )\n        if self._fit_to_content[\"column\"]:\n            self.labelList.setMinimumWidth(self.labelList.sizeHintForColumn(0) + 2)\n        # if text is None, the previous label in self.edit is kept\n        if text is None:\n            text = self.edit.text()\n        # description is always initialized by empty text c.f., self.edit.text\n        if description is None:\n            description = \"\"\n        self.editDescription.setPlainText(description)\n        if flags:\n            self.setFlags(flags)\n        else:\n            self.resetFlags(text)\n        if flags_disabled:\n            for i in range(self.flagsLayout.count()):\n                self.flagsLayout.itemAt(i).widget().setDisabled(True)\n        self.edit.setText(text)\n        self.edit.setSelection(0, len(text))\n        if group_id is None:\n            self.edit_group_id.clear()\n        else:\n            self.edit_group_id.setText(str(group_id))\n        items = self.labelList.findItems(text, QtCore.Qt.MatchFixedString)\n        if items:\n            if len(items) != 1:\n                logger.warning(f\"Label list has duplicate '{text}'\")\n            self.labelList.setCurrentItem(items[0])\n            row = self.labelList.row(items[0])\n            self.edit.completer().setCurrentRow(row)\n        self.edit.setFocus(QtCore.Qt.PopupFocusReason)\n        if move:\n            self.move(QtGui.QCursor.pos())\n        if self.exec_():\n            return (\n                self.edit.text(),\n                self.getFlags(),\n                self.getGroupId(),\n                self.editDescription.toPlainText(),\n            )\n        else:\n            return None, None, None, None\n"
  },
  {
    "path": "labelme/widgets/label_list_widget.py",
    "content": "from typing import cast\n\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\nfrom PyQt5.QtGui import QPalette\nfrom PyQt5.QtWidgets import QStyle\n\n\n# https://stackoverflow.com/a/2039745/4158863\nclass HTMLDelegate(QtWidgets.QStyledItemDelegate):\n    def __init__(self, parent=None):\n        super().__init__()\n        self.doc = QtGui.QTextDocument(self)\n\n    def paint(self, painter, option, index):\n        painter.save()\n\n        options = QtWidgets.QStyleOptionViewItem(option)\n\n        self.initStyleOption(options, index)\n        self.doc.setHtml(options.text)\n        options.text = \"\"\n\n        style = (\n            QtWidgets.QApplication.style()\n            if options.widget is None\n            else options.widget.style()\n        )\n        style.drawControl(QStyle.CE_ItemViewItem, options, painter)\n\n        ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()\n\n        if option.state & QStyle.State_Selected:\n            ctx.palette.setColor(\n                QPalette.Text,\n                option.palette.color(QPalette.Active, QPalette.HighlightedText),\n            )\n        else:\n            ctx.palette.setColor(\n                QPalette.Text,\n                option.palette.color(QPalette.Active, QPalette.Text),\n            )\n\n        textRect = style.subElementRect(QStyle.SE_ItemViewItemText, options)\n\n        if index.column() != 0:\n            textRect.adjust(5, 0, 0, 0)\n\n        thefuckyourshitup_constant = 4\n        margin = (option.rect.height() - options.fontMetrics.height()) // 2\n        margin = margin - thefuckyourshitup_constant\n        textRect.setTop(textRect.top() + margin)\n\n        painter.translate(textRect.topLeft())\n        painter.setClipRect(textRect.translated(-textRect.topLeft()))\n        self.doc.documentLayout().draw(painter, ctx)\n\n        painter.restore()\n\n    def sizeHint(self, option, index):\n        thefuckyourshitup_constant = 4\n        return QtCore.QSize(\n            int(self.doc.idealWidth()),\n            int(self.doc.size().height() - thefuckyourshitup_constant),\n        )\n\n\nclass LabelListWidgetItem(QtGui.QStandardItem):\n    def __init__(self, text=None, shape=None):\n        super().__init__()\n        self.setText(text or \"\")\n        self.setShape(shape)\n\n        self.setCheckable(True)\n        self.setCheckState(Qt.Checked)\n        self.setEditable(False)\n        self.setTextAlignment(Qt.AlignBottom)\n\n    def clone(self):\n        return LabelListWidgetItem(self.text(), self.shape())\n\n    def setShape(self, shape):\n        self.setData(shape, Qt.UserRole)\n\n    def shape(self):\n        return self.data(Qt.UserRole)\n\n    def __hash__(self):\n        return id(self)\n\n    def __repr__(self):\n        return f'{self.__class__.__name__}(\"{self.text()}\")'\n\n\nclass _ItemModel(QtGui.QStandardItemModel):\n    itemDropped = QtCore.pyqtSignal()\n\n    def removeRows(self, *args, **kwargs):\n        ret = super().removeRows(*args, **kwargs)\n        self.itemDropped.emit()\n        return ret\n\n    def dropMimeData(self, data, action, row: int, column: int, parent):\n        # NOTE: By default, PyQt will overwrite items when dropped on them, so we need\n        # to adjust the row/parent to insert after the item instead.\n\n        # If row is -1, we're dropping on an item (which would overwrite)\n        # Instead, we want to insert after it\n        if row == -1 and parent.isValid():\n            row = parent.row() + 1\n            parent = parent.parent()\n\n        # If still -1, append to end\n        if row == -1:\n            row = self.rowCount(parent)\n\n        return super().dropMimeData(data, action, row, column, parent)\n\n\nclass LabelListWidget(QtWidgets.QListView):\n    itemDoubleClicked = QtCore.pyqtSignal(LabelListWidgetItem)\n    itemSelectionChanged = QtCore.pyqtSignal(list, list)\n\n    def __init__(self):\n        super().__init__()\n        self._selectedItems = []\n\n        self.setWindowFlags(Qt.Window)\n\n        self._model: _ItemModel = _ItemModel()\n        self._model.setItemPrototype(LabelListWidgetItem())\n        self.setModel(self._model)\n\n        self.setItemDelegate(HTMLDelegate())\n        self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)\n        self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)\n        self.setDefaultDropAction(Qt.MoveAction)\n\n        self.doubleClicked.connect(self.itemDoubleClickedEvent)\n        self.selectionModel().selectionChanged.connect(self.itemSelectionChangedEvent)\n\n    def __len__(self):\n        return self._model.rowCount()\n\n    def __getitem__(self, i):\n        return self._model.item(i)\n\n    def __iter__(self):\n        for i in range(len(self)):\n            yield self[i]\n\n    @property\n    def itemDropped(self):\n        return self._model.itemDropped\n\n    @property\n    def itemChanged(self):\n        return self._model.itemChanged\n\n    def itemSelectionChangedEvent(self, selected, deselected):\n        selected = [self._model.itemFromIndex(i) for i in selected.indexes()]\n        deselected = [self._model.itemFromIndex(i) for i in deselected.indexes()]\n        self.itemSelectionChanged.emit(selected, deselected)\n\n    def itemDoubleClickedEvent(self, index):\n        self.itemDoubleClicked.emit(self._model.itemFromIndex(index))\n\n    def selectedItems(self):\n        return [self._model.itemFromIndex(i) for i in self.selectedIndexes()]\n\n    def scrollToItem(self, item):\n        self.scrollTo(self._model.indexFromItem(item))\n\n    def addItem(self, item):\n        if not isinstance(item, LabelListWidgetItem):\n            raise TypeError(\"item must be LabelListWidgetItem\")\n        self._model.setItem(self._model.rowCount(), 0, item)\n        item.setSizeHint(self.itemDelegate().sizeHint(None, None))  # type: ignore[arg-type,union-attr]\n\n    def removeItem(self, item):\n        index = self._model.indexFromItem(item)\n        self._model.removeRows(index.row(), 1)\n\n    def selectItem(self, item):\n        index = self._model.indexFromItem(item)\n        self.selectionModel().select(index, QtCore.QItemSelectionModel.Select)\n\n    def findItemByShape(self, shape):\n        for row in range(self._model.rowCount()):\n            item = self._model.item(row, 0)\n            item = cast(LabelListWidgetItem, item)\n            if item.shape() == shape:\n                return item\n        raise ValueError(f\"cannot find shape: {shape}\")\n\n    def clear(self):\n        self._model.clear()\n"
  },
  {
    "path": "labelme/widgets/tool_bar.py",
    "content": "from __future__ import annotations\n\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\n\nfrom .. import utils\n\n\nclass ToolBar(QtWidgets.QToolBar):\n    def __init__(\n        self,\n        title: str,\n        actions: list[QtWidgets.QAction | None],\n        orientation: Qt.Orientation = Qt.Horizontal,\n        button_style: Qt.ToolButtonStyle = Qt.ToolButtonTextUnderIcon,\n        font_base: QtGui.QFont | None = None,\n    ) -> None:\n        super().__init__(title)\n\n        if font_base:\n            font = QtGui.QFont(font_base)\n            font.setPointSizeF(font_base.pointSizeF() * 0.875)\n            self.setFont(font)\n\n        layout = self.layout()\n        m = (0, 0, 0, 0)\n        layout.setSpacing(0)\n        layout.setContentsMargins(*m)\n        self.setContentsMargins(*m)\n        self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint)\n        self.setMovable(False)\n        self.setFloatable(False)\n\n        self.setObjectName(f\"{title}ToolBar\")\n        self.setOrientation(orientation)\n        self.setToolButtonStyle(button_style)\n        utils.addActions(widget=self, actions=actions)\n\n    def addAction(self, action):  # type: ignore[override]\n        if isinstance(action, QtWidgets.QWidgetAction):\n            return super().addAction(action)\n        btn = QtWidgets.QToolButton()\n        btn.setDefaultAction(action)\n        btn.setToolButtonStyle(self.toolButtonStyle())\n        self.addWidget(btn)\n\n        # center align\n        for i in range(self.layout().count()):\n            if isinstance(self.layout().itemAt(i).widget(), QtWidgets.QToolButton):\n                self.layout().itemAt(i).setAlignment(QtCore.Qt.AlignCenter)\n"
  },
  {
    "path": "labelme/widgets/unique_label_qlist_widget.py",
    "content": "import html\n\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\n\nfrom .label_list_widget import HTMLDelegate\n\n\nclass _EscapableQListWidget(QtWidgets.QListWidget):\n    def keyPressEvent(self, keyEvent: QtGui.QKeyEvent) -> None:  # type: ignore\n        super().keyPressEvent(keyEvent)\n        if keyEvent.key() == Qt.Key_Escape:\n            self.clearSelection()\n\n\nclass UniqueLabelQListWidget(_EscapableQListWidget):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.setItemDelegate(HTMLDelegate(parent=self))\n\n    def mousePressEvent(self, mouseEvent: QtGui.QMouseEvent) -> None:  # type: ignore\n        super().mousePressEvent(mouseEvent)\n        if not self.indexAt(mouseEvent.pos()).isValid():\n            self.clearSelection()\n\n    def find_label_item(self, label: str) -> QtWidgets.QListWidgetItem | None:\n        for row in range(self.count()):\n            item = self.item(row)\n            if item and item.data(Qt.UserRole) == label:\n                return item\n        return None\n\n    def add_label_item(self, label: str, color: tuple[int, int, int]) -> None:\n        if self.find_label_item(label):\n            raise ValueError(f\"Item for label '{label}' already exists\")\n\n        item = QtWidgets.QListWidgetItem()\n        item.setData(Qt.UserRole, label)  # for find_label_item\n        item.setText(\n            f\"{html.escape(label)} \"\n            f\"<font color='#{color[0]:02x}{color[1]:02x}{color[2]:02x}'>●</font>\"\n        )\n        self.addItem(item)\n"
  },
  {
    "path": "labelme/widgets/zoom_widget.py",
    "content": "from PyQt5 import QtCore\nfrom PyQt5 import QtGui\nfrom PyQt5 import QtWidgets\n\n\nclass ZoomWidget(QtWidgets.QSpinBox):\n    def __init__(self, value=100):\n        super().__init__()\n        self.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)\n        self.setRange(1, 1000)\n        self.setSuffix(\" %\")\n        self.setValue(value)\n        self.setToolTip(\"Zoom Level\")\n        self.setStatusTip(self.toolTip())\n        self.setAlignment(QtCore.Qt.AlignCenter)\n\n    def minimumSizeHint(self):\n        height = super().minimumSizeHint().height()\n        fm = QtGui.QFontMetrics(self.font())\n        width = fm.width(str(self.maximum()))\n        return QtCore.QSize(width, height)\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"hatchling>=1.20.0\", \"hatch-vcs\", \"hatch-fancy-pypi-readme\"]\nbuild-backend = \"hatchling.build\"\n\n[project]\nname = \"labelme\"\ndescription = \"Image annotation with Python.\"\nlicense = { text = \"GPL-3.0-only\" }\nrequires-python = \">=3.10\"\nauthors = [{ name = \"Kentaro Wada\", email = \"www.kentaro.wada@gmail.com\" }]\nclassifiers = [\n  \"Development Status :: 5 - Production/Stable\",\n  \"Intended Audience :: Developers\",\n  \"Intended Audience :: Science/Research\",\n  \"License :: OSI Approved :: GNU General Public License v3 (GPLv3)\",\n  \"Operating System :: OS Independent\",\n  \"Programming Language :: Python\",\n  \"Programming Language :: Python :: 3 :: Only\",\n  \"Programming Language :: Python :: 3.10\",\n  \"Programming Language :: Python :: 3.11\",\n  \"Programming Language :: Python :: 3.12\",\n  \"Programming Language :: Python :: 3.13\",\n]\ndependencies = [\n  \"imgviz>=2.0.0\",\n  \"loguru\",\n  \"matplotlib\",\n  \"natsort>=7.1.0\",\n  \"numpy\",\n  \"osam>=0.3.1\",\n  \"pillow>=2.8\",\n  \"pyqt5>=5.14.0\",\n  \"pyqt5-qt5!=5.15.13 ; sys_platform == 'linux'\",\n  \"pyqt5-qt5!=5.15.11,!=5.15.12,!=5.15.13,!=5.15.14,!=5.15.15,!=5.15.16 ; sys_platform == 'win32'\",\n  \"pyyaml\",\n  \"scikit-image\",\n  \"tifffile\",\n]\ndynamic = [\"readme\", \"version\"]\n\n[tool.hatch.metadata.hooks.fancy-pypi-readme]\ncontent-type = \"text/markdown\"\nfragments = [{ path = \"README.md\" }]\n\n[tool.hatch.version]\nsource = \"vcs\"\n\n[dependency-groups]\ndev = [\n  \"ipython\",\n  \"pyqt5-stubs>=5.15.6.0\",\n  \"pytest>=8.3.4\",\n  \"pytest-qt>=4.4.0\",\n  \"ruff~=0.12.11\",\n  \"twine>=6.1.0\",\n  \"ty>=0.0.1a29\",\n  \"types-pillow>=10.2.0.20240822\",\n  \"types-pyyaml>=6.0.12.20241230\",\n]\n\n[project.scripts]\nlabelme = \"labelme.__main__:main\"\n\n[tool.pytest.ini_options]\nqt_api = \"pyqt5\"\nmarkers = [\n  \"gui: mark a test as a GUI test.\",\n]\n\n[tool.ruff.lint]\nselect = [\n  \"E\",  # pycodestyle\n  \"F\",  # pyflakes\n  \"I\",  # isort\n  \"UP\",  # pyupgrade\n]\n\n[tool.ruff.lint.isort]\nforce-single-line = true\n\n[tool.ruff.lint.per-file-ignores]\n\"__init__.py\" = [\"F401\"]\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "import json\nimport shutil\nfrom pathlib import Path\n\nimport pytest\n\n\ndef _create_annotated_nested(data_path: Path) -> None:\n    dst_dir: Path = data_path / \"annotated_nested\"\n    dst_dir.mkdir()\n\n    (dst_dir / \"images\").mkdir()\n    for image_file in (data_path / \"annotated\").glob(\"*.jpg\"):\n        shutil.copy(image_file, dst_dir / \"images\" / image_file.name)\n\n    (dst_dir / \"annotations\").mkdir()\n    for json_file in (data_path / \"annotated\").glob(\"*.json\"):\n        dst_json_file = dst_dir / \"annotations\" / json_file.name\n        shutil.copy(json_file, dst_json_file)\n        with open(dst_json_file) as f:\n            json_data = json.load(f)\n        json_data[\"imagePath\"] = str(Path(\"..\") / \"images\" / json_data[\"imagePath\"])\n        with open(dst_json_file, \"w\") as f:\n            json.dump(json_data, f, indent=2)\n\n\n@pytest.fixture(scope=\"function\")\ndef data_path(tmp_path: Path) -> Path:\n    data_path: Path = tmp_path / \"data\"\n    shutil.copytree(Path(__file__).parent / \"data\", data_path)\n\n    _create_annotated_nested(data_path=data_path)\n\n    return data_path\n"
  },
  {
    "path": "tests/e2e/__init__.py",
    "content": ""
  },
  {
    "path": "tests/e2e/annotation_test.py",
    "content": "from __future__ import annotations\n\nfrom pathlib import Path\n\nimport pytest\nfrom PyQt5.QtCore import QPoint\nfrom PyQt5.QtCore import QSize\nfrom PyQt5.QtCore import Qt\nfrom PyQt5.QtCore import QTimer\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\nimport labelme.testing\n\nfrom .conftest import show_window_and_wait_for_imagedata\n\n\n@pytest.mark.gui\ndef test_MainWindow_annotate_jpg(\n    qtbot: QtBot,\n    data_path: Path,\n    tmp_path: Path,\n) -> None:\n    input_file: str = str(data_path / \"raw/2011_000003.jpg\")\n    out_file: str = str(tmp_path / \"2011_000003.json\")\n\n    win: labelme.app.MainWindow = labelme.app.MainWindow(\n        filename=input_file,\n        config_overrides=dict(auto_save=True),\n        output_dir=str(tmp_path),\n    )\n    qtbot.addWidget(win)\n    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)\n\n    label: str = \"whole\"\n    canvas_size: QSize = win._canvas_widgets.canvas.size()\n    points: list[tuple[float, float]] = [\n        (canvas_size.width() * 0.25, canvas_size.height() * 0.25),\n        (canvas_size.width() * 0.75, canvas_size.height() * 0.25),\n        (canvas_size.width() * 0.75, canvas_size.height() * 0.75),\n        (canvas_size.width() * 0.25, canvas_size.height() * 0.75),\n    ]\n    win._switch_canvas_mode(edit=False, createMode=\"polygon\")\n    qtbot.wait(50)\n\n    def click(xy: tuple[float, float]) -> None:\n        qtbot.mouseMove(win._canvas_widgets.canvas, pos=QPoint(int(xy[0]), int(xy[1])))\n        qtbot.wait(50)\n        qtbot.mousePress(\n            win._canvas_widgets.canvas,\n            Qt.LeftButton,\n            pos=QPoint(int(xy[0]), int(xy[1])),\n        )\n        qtbot.wait(50)\n\n    for xy in points:\n        click(xy=xy)\n\n    def interact() -> None:\n        qtbot.keyClicks(win._label_dialog.edit, label)\n        qtbot.wait(50)\n        qtbot.keyClick(win._label_dialog.edit, Qt.Key_Enter)\n        qtbot.wait(50)\n\n    QTimer.singleShot(100, interact)\n\n    click(xy=points[0])\n\n    assert len(win._canvas_widgets.canvas.shapes) == 1\n    assert len(win._canvas_widgets.canvas.shapes[0].points) == 4\n    assert win._canvas_widgets.canvas.shapes[0].label == \"whole\"\n    assert win._canvas_widgets.canvas.shapes[0].shape_type == \"polygon\"\n    assert win._canvas_widgets.canvas.shapes[0].group_id is None\n    assert win._canvas_widgets.canvas.shapes[0].mask is None\n    assert win._canvas_widgets.canvas.shapes[0].flags == {}\n\n    win.saveFile()\n\n    labelme.testing.assert_labelfile_sanity(out_file)\n\n    win.close()\n"
  },
  {
    "path": "tests/e2e/config_test.py",
    "content": "from __future__ import annotations\n\nfrom pathlib import Path\n\nimport pytest\nfrom PyQt5 import QtWidgets\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\n\n\n@pytest.mark.gui\n@pytest.mark.parametrize(\n    \"with_config_file\",\n    [\n        pytest.param(True, id=\"with_config_file\"),\n        pytest.param(False, id=\"without_config_file\"),\n    ],\n)\ndef test_MainWindow_config(\n    with_config_file: bool,\n    qtbot: QtBot,\n    tmp_path: Path,\n    monkeypatch: pytest.MonkeyPatch,\n) -> None:\n    config_file: Path | None = None\n    auto_save: bool = True\n    if with_config_file:\n        config_file = tmp_path / \"labelmerc.yaml\"\n        config_file.write_text(\"auto_save: false\\nlabels: [cat, dog]\\n\")\n        auto_save = False\n\n    win: labelme.app.MainWindow = labelme.app.MainWindow(\n        config_file=config_file,\n        config_overrides={\"labels\": [\"bird\"]},\n    )\n    qtbot.addWidget(win)\n    win.show()\n\n    assert win._config[\"auto_save\"] is auto_save\n    assert win._config[\"labels\"] == [\"bird\"]\n    assert win._config_file == config_file\n\n    if not with_config_file:\n        message_box_shown: list[bool] = [False]\n\n        def mock_information(parent, title, message):\n            message_box_shown[0] = True\n            assert \"No Config File\" in title\n            return QtWidgets.QMessageBox.Ok\n\n        monkeypatch.setattr(QtWidgets.QMessageBox, \"information\", mock_information)\n\n        win._open_config_file()\n        assert message_box_shown[0] is True\n\n    win.close()\n"
  },
  {
    "path": "tests/e2e/conftest.py",
    "content": "from __future__ import annotations\n\nfrom collections.abc import Generator\nfrom pathlib import Path\n\nimport pytest\nfrom PyQt5.QtCore import QSettings\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\n\n\n@pytest.fixture(autouse=True)\ndef _isolated_qtsettings(\n    tmp_path: Path, monkeypatch: pytest.MonkeyPatch\n) -> Generator[None, None, None]:\n    settings_file = tmp_path / \"qtsettings.ini\"\n    settings: QSettings = QSettings(str(settings_file), QSettings.IniFormat)\n    monkeypatch.setattr(\n        labelme.app.QtCore, \"QSettings\", lambda *args, **kwargs: settings\n    )\n    yield\n\n\ndef show_window_and_wait_for_imagedata(\n    qtbot: QtBot, win: labelme.app.MainWindow\n) -> None:\n    win.show()\n\n    def check_imageData() -> None:\n        assert hasattr(win, \"imageData\")\n        assert win.imageData is not None\n\n    qtbot.waitUntil(check_imageData)\n"
  },
  {
    "path": "tests/e2e/file_loading_test.py",
    "content": "from __future__ import annotations\n\nfrom pathlib import Path\nfrom typing import Literal\n\nimport pytest\nfrom PyQt5 import QtWidgets\nfrom PyQt5.QtCore import Qt\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\nimport labelme.testing\n\nfrom .conftest import show_window_and_wait_for_imagedata\n\n\n@pytest.mark.gui\ndef test_MainWindow_open_img(\n    qtbot: QtBot,\n    data_path: Path,\n) -> None:\n    image_file: str = str(data_path / \"raw/2011_000003.jpg\")\n    win: labelme.app.MainWindow = labelme.app.MainWindow(filename=image_file)\n    qtbot.addWidget(win)\n    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)\n    win.close()\n\n\n@pytest.mark.gui\ndef test_MainWindow_open_json(\n    qtbot: QtBot,\n    data_path: Path,\n) -> None:\n    json_files: list[str] = [\n        str(data_path / \"annotated_with_data/apc2016_obj3.json\"),\n        str(data_path / \"annotated/2011_000003.json\"),\n    ]\n    json_file: str\n    for json_file in json_files:\n        labelme.testing.assert_labelfile_sanity(json_file)\n\n        win: labelme.app.MainWindow = labelme.app.MainWindow(filename=json_file)\n        qtbot.addWidget(win)\n        show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)\n        win.close()\n\n\n@pytest.mark.gui\n@pytest.mark.parametrize(\"scenario\", [\"raw\", \"annotated\", \"annotated_nested\"])\ndef test_MainWindow_open_dir(\n    qtbot: QtBot,\n    scenario: Literal[\"raw\", \"annotated\", \"annotated_nested\"],\n    data_path: Path,\n) -> None:\n    directory: str\n    output_dir: str | None\n    if scenario == \"annotated_nested\":\n        directory = str(data_path / \"annotated_nested\" / \"images\")\n        output_dir = str(data_path / \"annotated_nested\" / \"annotations\")\n    else:\n        directory = str(data_path / scenario)\n        output_dir = None\n\n    win: labelme.app.MainWindow = labelme.app.MainWindow(\n        filename=directory, output_dir=output_dir\n    )\n    qtbot.addWidget(win)\n    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)\n\n    first_image_name: str = \"2011_000003.jpg\"\n    second_image_name: str = \"2011_000006.jpg\"\n\n    assert win._image_path\n    assert Path(win._image_path).name == first_image_name\n    win._open_prev_image()\n    qtbot.wait(100)\n    assert Path(win._image_path).name == first_image_name\n\n    win._open_next_image()\n    qtbot.wait(100)\n    assert Path(win._image_path).name == second_image_name\n    win._open_prev_image()\n    qtbot.wait(100)\n    assert Path(win._image_path).name == first_image_name\n\n    assert win._docks.file_list.count() == 3\n    expected_check_state = (\n        Qt.Checked if scenario.startswith(\"annotated\") else Qt.Unchecked\n    )\n    for index in range(win._docks.file_list.count()):\n        item: QtWidgets.QListWidgetItem | None = win._docks.file_list.item(index)\n        assert item\n        assert item.checkState() == expected_check_state\n"
  },
  {
    "path": "tests/e2e/navigation_test.py",
    "content": "from __future__ import annotations\n\nfrom pathlib import Path\n\nimport pytest\nfrom PyQt5.QtCore import QPoint\nfrom PyQt5.QtCore import Qt\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\n\nfrom .conftest import show_window_and_wait_for_imagedata\n\n\n@pytest.mark.gui\ndef test_image_navigation_while_selecting_shape(\n    qtbot: QtBot,\n    data_path: Path,\n) -> None:\n    win: labelme.app.MainWindow = labelme.app.MainWindow(\n        filename=str(data_path / \"annotated\")\n    )\n    qtbot.addWidget(win)\n    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)\n\n    # Incident: https://github.com/wkentaro/labelme/pull/1716 {{\n    point = QPoint(250, 200)\n    qtbot.mouseMove(win._canvas_widgets.canvas, pos=point)\n    qtbot.mouseClick(win._canvas_widgets.canvas, Qt.LeftButton, pos=point)\n    qtbot.wait(100)\n\n    qtbot.mouseClick(win._docks.file_list, Qt.LeftButton)\n    qtbot.wait(100)\n\n    qtbot.keyClick(win._docks.file_list, Qt.Key_Down)\n    qtbot.wait(100)\n    qtbot.keyClick(win._canvas_widgets.canvas, Qt.Key_Down)\n    qtbot.wait(100)\n    # }}\n\n    win.close()\n"
  },
  {
    "path": "tests/e2e/smoke_test.py",
    "content": "from __future__ import annotations\n\nfrom pathlib import Path\n\nimport pytest\nfrom pytestqt.qtbot import QtBot\n\nimport labelme.app\n\n\n@pytest.mark.gui\ndef test_MainWindow_open(qtbot: QtBot) -> None:\n    win: labelme.app.MainWindow = labelme.app.MainWindow()\n    qtbot.addWidget(win)\n    win.show()\n    win.close()\n\n\n@pytest.mark.gui\ndef test_file_search_config_filters_on_startup(qtbot: QtBot, data_path: Path) -> None:\n    raw_dir = data_path / \"raw\"\n    all_images = list(raw_dir.glob(\"*.jpg\"))\n    assert len(all_images) == 3\n\n    win = labelme.app.MainWindow(\n        config_overrides={\"file_search\": \"2011_000003\"},\n        filename=str(raw_dir),\n    )\n    qtbot.addWidget(win)\n    win.show()\n\n    assert win._docks.file_search.text() == \"2011_000003\"\n    assert win._docks.file_list.count() == 1\n\n    win.close()\n"
  },
  {
    "path": "tests/unit/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/_label_file_test.py",
    "content": "from __future__ import annotations\n\nimport json\nimport shutil\nfrom pathlib import Path\n\nfrom labelme._label_file import LabelFile\n\n\ndef test_LabelFile_load_windows_path(data_path: Path, tmp_path: Path) -> None:\n    \"\"\"Test that LabelFile can load JSON with Windows-style backslash paths.\n\n    Regression test for https://github.com/wkentaro/labelme/issues/1725\n    \"\"\"\n    (tmp_path / \"images\").mkdir()\n    shutil.copy(\n        data_path / \"annotated\" / \"2011_000003.jpg\",\n        tmp_path / \"images\" / \"2011_000003.jpg\",\n    )\n\n    json_file = tmp_path / \"annotations\" / \"2011_000003.json\"\n    json_file.parent.mkdir()\n    with open(data_path / \"annotated\" / \"2011_000003.json\") as f:\n        json_data = json.load(f)\n    json_data[\"imagePath\"] = \"..\\\\images\\\\2011_000003.jpg\"\n    with open(json_file, \"w\") as f:\n        json.dump(json_data, f)\n\n    label_file = LabelFile(str(json_file))\n    assert label_file.imagePath == \"../images/2011_000003.jpg\"\n    assert label_file.imageData is not None\n"
  },
  {
    "path": "tests/unit/config_test.py",
    "content": "from pathlib import Path\n\nimport pytest\nimport yaml\n\nfrom labelme.config import _migrate_config_from_file\nfrom labelme.config import get_user_config_file\nfrom labelme.config import load_config\n\n\ndef test_get_user_config_file_creates_sparse(tmp_path, monkeypatch):\n    monkeypatch.setenv(\"HOME\", str(tmp_path))\n    config_file = get_user_config_file()\n    content = Path(config_file).read_text()\n    assert content.startswith(\"# Labelme config file\")\n    parsed = yaml.safe_load(content)\n    assert parsed is None\n\n\ndef test_get_user_config_file_does_not_overwrite(tmp_path, monkeypatch):\n    monkeypatch.setenv(\"HOME\", str(tmp_path))\n    config_path = tmp_path / \".labelmerc\"\n    config_path.write_text(\"auto_save: true\\n\")\n    config_file = get_user_config_file()\n    content = Path(config_file).read_text()\n    assert content == \"auto_save: true\\n\"\n\n\ndef test_get_user_config_file_skip_creation(tmp_path, monkeypatch):\n    monkeypatch.setenv(\"HOME\", str(tmp_path))\n    config_file = get_user_config_file(create_if_missing=False)\n    assert not Path(config_file).exists()\n\n\n@pytest.mark.parametrize(\"old_value\", [True, False])\ndef test_migrate_store_data_to_with_image_data(tmp_path, old_value):\n    config_file = tmp_path / \"config.yaml\"\n    config_file.write_text(f\"store_data: {str(old_value).lower()}\\n\")\n    config = load_config(config_file=config_file, config_overrides={})\n    assert config[\"with_image_data\"] is old_value\n    assert \"store_data\" not in config\n\n\n@pytest.mark.parametrize(\n    \"input_name, expected_name\",\n    [\n        (\"SegmentAnything (balanced)\", \"Sam (balanced)\"),\n        (\"SegmentAnything (tiny)\", \"Sam (tiny)\"),\n        (\"Sam (balanced)\", \"Sam (balanced)\"),\n        (\"Sam (large)\", \"Sam (large)\"),\n        (\"Sam2 (balanced)\", \"Sam2 (balanced)\"),\n    ],\n)\ndef test_migrate_ai_model_name(input_name: str, expected_name: str) -> None:\n    config: dict = {\"ai\": {\"default\": input_name}}\n    _migrate_config_from_file(config)\n    assert config[\"ai\"][\"default\"] == expected_name\n\n\n_POLYGON_TO_SHAPE_RENAMES = {\n    \"edit_polygon\": \"edit_shape\",\n    \"delete_polygon\": \"delete_shape\",\n    \"duplicate_polygon\": \"duplicate_shape\",\n    \"copy_polygon\": \"copy_shape\",\n    \"paste_polygon\": \"paste_shape\",\n    \"show_all_polygons\": \"show_all_shapes\",\n    \"hide_all_polygons\": \"hide_all_shapes\",\n    \"toggle_all_polygons\": \"toggle_all_shapes\",\n}\n\n\n@pytest.mark.parametrize(\n    \"old_key, new_key\",\n    list(_POLYGON_TO_SHAPE_RENAMES.items()),\n    ids=list(_POLYGON_TO_SHAPE_RENAMES.keys()),\n)\ndef test_migrate_polygon_shortcut_to_shape(old_key, new_key):\n    config = {\"shortcuts\": {old_key: \"Ctrl+X\"}}\n    _migrate_config_from_file(config)\n    assert old_key not in config[\"shortcuts\"]\n    assert config[\"shortcuts\"][new_key] == \"Ctrl+X\"\n\n\ndef test_migrate_polygon_shortcuts_no_shortcuts_key():\n    config = {}\n    _migrate_config_from_file(config)\n    assert \"shortcuts\" not in config\n\n\ndef test_migrate_polygon_shortcut_skips_when_new_key_exists():\n    config = {\"shortcuts\": {\"edit_polygon\": \"Ctrl+X\", \"edit_shape\": \"Ctrl+Y\"}}\n    _migrate_config_from_file(config)\n    assert config[\"shortcuts\"][\"edit_shape\"] == \"Ctrl+Y\"\n    assert \"edit_polygon\" in config[\"shortcuts\"]\n"
  },
  {
    "path": "tests/unit/load_image_file_test.py",
    "content": "from __future__ import annotations\n\nimport io\nfrom pathlib import Path\n\nimport numpy as np\nimport PIL.Image\nimport tifffile\n\nfrom labelme._label_file import LabelFile\n\n\ndef _make_image(tmp_path: Path, filename: str, mode: str = \"RGB\", size=(100, 100)):\n    channels = 4 if mode == \"RGBA\" else 3\n    arr = np.random.randint(0, 255, (size[1], size[0], channels), dtype=np.uint8)\n    path = tmp_path / filename\n    PIL.Image.fromarray(arr, mode=mode).save(str(path))\n    return path\n\n\ndef test_tiff_without_alpha_encoded_as_jpeg(tmp_path):\n    path = _make_image(tmp_path, \"test.tiff\")\n    data = LabelFile.load_image_file(str(path))\n    assert data[:2] == b\"\\xff\\xd8\"\n\n\ndef test_tiff_with_alpha_encoded_as_png(tmp_path):\n    path = _make_image(tmp_path, \"test.tiff\", mode=\"RGBA\")\n    data = LabelFile.load_image_file(str(path))\n    assert data[:4] == b\"\\x89PNG\"\n\n\ndef test_jpeg_returns_raw_bytes(tmp_path):\n    path = _make_image(tmp_path, \"test.jpg\")\n    data = LabelFile.load_image_file(str(path))\n    assert data == path.read_bytes()\n\n\ndef test_png_returns_raw_bytes(tmp_path):\n    path = _make_image(tmp_path, \"test.png\")\n    data = LabelFile.load_image_file(str(path))\n    assert data == path.read_bytes()\n\n\ndef test_multispectral_tiff_float32(tmp_path):\n    arr = np.random.rand(64, 64, 5).astype(np.float32) * 0.5\n    path = tmp_path / \"multispectral.tif\"\n    tifffile.imwrite(str(path), arr)\n\n    data = LabelFile.load_image_file(str(path))\n    assert data[:2] == b\"\\xff\\xd8\"\n\n    img = PIL.Image.open(io.BytesIO(data))\n    assert img.mode == \"RGB\"\n    assert img.size == (64, 64)\n\n\ndef test_grayscale_tiff_float32(tmp_path):\n    arr = np.random.rand(64, 64).astype(np.float32)\n    path = tmp_path / \"grayscale.tif\"\n    tifffile.imwrite(str(path), arr)\n\n    data = LabelFile.load_image_file(str(path))\n    img = PIL.Image.open(io.BytesIO(data))\n    assert img.size == (64, 64)\n\n\ndef test_constant_value_tiff_returns_black(tmp_path):\n    arr = np.full((64, 64), 42.0, dtype=np.float32)\n    path = tmp_path / \"constant.tif\"\n    tifffile.imwrite(str(path), arr)\n\n    data = LabelFile.load_image_file(str(path))\n    img = PIL.Image.open(io.BytesIO(data))\n    assert img.size == (64, 64)\n    assert np.array(img).max() == 0\n\n\ndef test_two_band_tiff_falls_back_to_first_band(tmp_path):\n    arr = np.random.rand(64, 64, 2).astype(np.float32)\n    path = tmp_path / \"twoband.tif\"\n    tifffile.imwrite(str(path), arr)\n\n    data = LabelFile.load_image_file(str(path))\n    img = PIL.Image.open(io.BytesIO(data))\n    assert img.size == (64, 64)\n"
  },
  {
    "path": "tests/unit/shape_contains_point_test.py",
    "content": "from __future__ import annotations\n\nfrom PyQt5 import QtCore\n\nfrom labelme.shape import Shape\n\n\ndef _make_point_shape(x: float, y: float) -> Shape:\n    \"\"\"Create a point shape with a single point at (x, y).\"\"\"\n    shape = Shape(shape_type=\"point\")\n    shape.addPoint(QtCore.QPointF(x, y))\n    return shape\n\n\ndef test_point_shape_contains_center():\n    \"\"\"Clicking exactly on a point shape should return True.\"\"\"\n    shape = _make_point_shape(100.0, 200.0)\n    assert shape.containsPoint(QtCore.QPointF(100.0, 200.0)) is True\n\n\ndef test_point_shape_contains_within_radius():\n    \"\"\"Clicking within point_size/2 of the center should return True.\"\"\"\n    shape = _make_point_shape(100.0, 200.0)\n    # point_size defaults to 8, so radius = 4. A point 3px away should hit.\n    assert shape.containsPoint(QtCore.QPointF(103.0, 200.0)) is True\n\n\ndef test_point_shape_at_exact_boundary():\n    \"\"\"Clicking exactly at point_size/2 distance should return True (inclusive).\"\"\"\n    shape = _make_point_shape(100.0, 200.0)\n    # point_size defaults to 8, so radius = 4. Exactly 4px away should hit.\n    assert shape.containsPoint(QtCore.QPointF(104.0, 200.0)) is True\n\n\ndef test_point_shape_outside_radius():\n    \"\"\"Clicking more than point_size/2 away should return False.\"\"\"\n    shape = _make_point_shape(100.0, 200.0)\n    # 10px away, well outside the radius of 4\n    assert shape.containsPoint(QtCore.QPointF(110.0, 200.0)) is False\n\n\ndef test_point_shape_empty_points():\n    \"\"\"A point shape with no points should return False, not raise.\"\"\"\n    shape = Shape(shape_type=\"point\")\n    assert shape.containsPoint(QtCore.QPointF(0.0, 0.0)) is False\n"
  },
  {
    "path": "tests/unit/shape_test.py",
    "content": "import numpy as np\nimport pytest\nfrom numpy.typing import NDArray\nfrom PyQt5 import QtCore\n\nfrom labelme.shape import Shape\n\n\ndef _make_mask_shape(\n    mask: NDArray[np.bool_], origin_x: float, origin_y: float\n) -> Shape:\n    shape = Shape(shape_type=\"mask\")\n    h, w = mask.shape\n    shape.addPoint(QtCore.QPointF(origin_x, origin_y))\n    shape.addPoint(QtCore.QPointF(origin_x + w, origin_y + h))\n    shape.mask = mask\n    return shape\n\n\n@pytest.mark.parametrize(\n    \"point, expected\",\n    [\n        ((4, 3), True),  # inside True region\n        ((4, 4), True),  # last valid row/column\n        ((5, 2), False),  # one pixel past right boundary\n        ((2, 5), False),  # one pixel past bottom boundary\n        ((5, 5), False),  # past both boundaries\n    ],\n)\ndef test_mask_contains_point(point: tuple[int, int], expected: bool) -> None:\n    mask = np.ones((5, 5), dtype=bool)\n    shape = _make_mask_shape(mask, origin_x=0, origin_y=0)\n    assert shape.containsPoint(QtCore.QPointF(*point)) is expected\n"
  },
  {
    "path": "tests/unit/utils/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/utils/image_test.py",
    "content": "import numpy as np\nimport PIL.Image\n\nfrom labelme.utils import image as image_module\n\nfrom .util import data_dir\nfrom .util import get_img_and_data\n\n\ndef test_img_b64_to_arr():\n    img, _ = get_img_and_data()\n    assert img.dtype == np.uint8\n    assert img.shape == (907, 1210, 3)\n\n\ndef test_img_arr_to_b64():\n    img_file = data_dir / \"annotated_with_data/apc2016_obj3.jpg\"\n    img_arr = np.asarray(PIL.Image.open(img_file))\n    img_b64 = image_module.img_arr_to_b64(img_arr)\n    img_arr2 = image_module.img_b64_to_arr(img_b64)\n    np.testing.assert_allclose(img_arr, img_arr2)\n\n\ndef test_img_data_to_png_data():\n    img_file = data_dir / \"annotated_with_data/apc2016_obj3.jpg\"\n    with open(img_file, \"rb\") as f:\n        img_data = f.read()\n    png_data = image_module.img_data_to_png_data(img_data)\n    assert isinstance(png_data, bytes)\n"
  },
  {
    "path": "tests/unit/utils/qt_test.py",
    "content": "from PyQt5.QtCore import QPointF\n\nfrom labelme.utils.qt import distancetoline\n\n\ndef test_distancetoline():\n    line = (QPointF(0, 0), QPointF(10, 0))\n\n    assert distancetoline(QPointF(5, 0), line) == 0\n    assert distancetoline(QPointF(5, 5), line) == 5\n    assert distancetoline(QPointF(0, 0), line) == 0\n    assert distancetoline(QPointF(-5, 0), line) == 5\n    assert distancetoline(QPointF(15, 0), line) == 5\n"
  },
  {
    "path": "tests/unit/utils/shape_test.py",
    "content": "import numpy as np\n\nfrom labelme.utils import shape as shape_module\n\nfrom .util import get_img_and_data\n\n\ndef test_shapes_to_label():\n    img, data = get_img_and_data()\n    label_name_to_value = {}\n    for shape in data[\"shapes\"]:\n        label_name = shape[\"label\"]\n        label_value = len(label_name_to_value)\n        label_name_to_value[label_name] = label_value\n    cls, _ = shape_module.shapes_to_label(\n        img.shape, data[\"shapes\"], label_name_to_value\n    )\n    assert cls.shape == img.shape[:2]\n\n\ndef test_shape_to_mask():\n    img, data = get_img_and_data()\n    for shape in data[\"shapes\"]:\n        points = shape[\"points\"]\n        mask = shape_module.shape_to_mask(img.shape[:2], points)\n        assert mask.shape == img.shape[:2]\n\n\ndef test_shape_to_mask_rectangle_reversed_coords():\n    img_shape = (100, 100)\n    mask_tl_br = shape_module.shape_to_mask(\n        img_shape, [[10, 10], [50, 50]], shape_type=\"rectangle\"\n    )\n    mask_br_tl = shape_module.shape_to_mask(\n        img_shape, [[50, 50], [10, 10]], shape_type=\"rectangle\"\n    )\n    mask_tr_bl = shape_module.shape_to_mask(\n        img_shape, [[50, 10], [10, 50]], shape_type=\"rectangle\"\n    )\n    mask_bl_tr = shape_module.shape_to_mask(\n        img_shape, [[10, 50], [50, 10]], shape_type=\"rectangle\"\n    )\n    assert np.array_equal(mask_tl_br, mask_br_tl)\n    assert np.array_equal(mask_tl_br, mask_tr_bl)\n    assert np.array_equal(mask_tl_br, mask_bl_tr)\n    assert mask_tl_br.sum() > 0\n"
  },
  {
    "path": "tests/unit/utils/util.py",
    "content": "import json\nfrom pathlib import Path\n\nfrom labelme.utils import image as image_module\nfrom labelme.utils import shape as shape_module\n\nhere = Path(__file__).parent\ndata_dir = here.parent.parent / \"data\"\n\n\ndef get_img_and_data():\n    json_file = data_dir / \"annotated_with_data/apc2016_obj3.json\"\n    with open(json_file) as f:\n        data = json.load(f)\n    img_b64 = data[\"imageData\"]\n    img = image_module.img_b64_to_arr(img_b64)\n    return img, data\n\n\ndef get_img_and_lbl():\n    img, data = get_img_and_data()\n\n    label_name_to_value = {\"__background__\": 0}\n    for shape in data[\"shapes\"]:\n        label_name = shape[\"label\"]\n        label_value = len(label_name_to_value)\n        label_name_to_value[label_name] = label_value\n\n    n_labels = max(label_name_to_value.values()) + 1\n    label_names = [None] * n_labels\n    for label_name, label_value in label_name_to_value.items():\n        label_names[label_value] = label_name\n\n    lbl, _ = shape_module.shapes_to_label(\n        img.shape, data[\"shapes\"], label_name_to_value\n    )\n    return img, lbl, label_names\n"
  },
  {
    "path": "tests/unit/widgets/__init__.py",
    "content": ""
  },
  {
    "path": "tests/unit/widgets/canvas_test.py",
    "content": "from __future__ import annotations\n\nfrom typing import Final\n\nimport pytest\nfrom PyQt5 import QtGui\nfrom PyQt5.QtCore import QPointF\n\nfrom labelme.widgets.canvas import Canvas\n\n_WIDTH: Final = 100\n_HEIGHT: Final = 50\n\n\n@pytest.fixture()\ndef canvas(qtbot) -> Canvas:\n    canvas = Canvas()\n    canvas.pixmap = QtGui.QPixmap(_WIDTH, _HEIGHT)\n    qtbot.addWidget(canvas)\n    return canvas\n\n\n@pytest.mark.gui\n@pytest.mark.parametrize(\n    (\"point\", \"is_outside\"),\n    [\n        (QPointF(_WIDTH / 2, _HEIGHT / 2), False),\n        (QPointF(0, 0), False),\n        (QPointF(_WIDTH, _HEIGHT), False),\n        (QPointF(_WIDTH, _HEIGHT / 2), False),\n        (QPointF(_WIDTH / 2, _HEIGHT), False),\n        (QPointF(_WIDTH + 0.1, _HEIGHT / 2), True),\n        (QPointF(_WIDTH / 2, _HEIGHT + 0.1), True),\n        (QPointF(-0.1, _HEIGHT / 2), True),\n        (QPointF(_WIDTH / 2, -0.1), True),\n    ],\n)\ndef test_outOfPixmap(canvas: Canvas, point: QPointF, is_outside: bool):\n    assert canvas.outOfPixmap(point) is is_outside\n\n\n@pytest.mark.gui\n@pytest.mark.parametrize(\n    (\"p1\", \"p2\", \"pt_intersection\"),\n    [\n        (\n            pt_center := QPointF(_WIDTH / 2, _HEIGHT / 2),\n            QPointF(_WIDTH + 50, _HEIGHT / 2),  # to the right\n            QPointF(_WIDTH, _HEIGHT / 2),  # right edge\n        ),\n        (\n            pt_center,\n            QPointF(_WIDTH / 2, -10),  # to the top\n            QPointF(_WIDTH / 2, 0),  # top edge\n        ),\n        (\n            pt_center,\n            QPointF(-10, _HEIGHT / 2),  # to the left\n            QPointF(0, _HEIGHT / 2),  # left edge\n        ),\n        (\n            pt_center,\n            QPointF(_WIDTH / 2, _HEIGHT + 30),  # to the bottom\n            QPointF(_WIDTH / 2, _HEIGHT),  # bottom edge\n        ),\n    ],\n)\ndef test_intersectionPoint(\n    canvas: Canvas, p1: QPointF, p2: QPointF, pt_intersection: QPointF\n):\n    assert canvas.intersectionPoint(p1, p2) == pt_intersection\n"
  },
  {
    "path": "tests/unit/widgets/label_dialog_test.py",
    "content": "from __future__ import annotations\n\nimport pytest\nfrom PyQt5 import QtCore\nfrom PyQt5 import QtWidgets\n\nfrom labelme.widgets import LabelDialog\nfrom labelme.widgets import LabelQLineEdit\n\n\n@pytest.mark.gui\ndef test_LabelQLineEdit(qtbot):\n    list_widget = QtWidgets.QListWidget()\n    list_widget.addItems([\"cat\", \"dog\", \"person\"])\n    widget = LabelQLineEdit()\n    widget.setListWidget(list_widget)\n    qtbot.addWidget(widget)\n\n    # key press to navigate in label list\n    item = widget.list_widget.findItems(\"cat\", QtCore.Qt.MatchExactly)[0]\n    widget.list_widget.setCurrentItem(item)\n    assert widget.list_widget.currentItem().text() == \"cat\"\n    qtbot.keyPress(widget, QtCore.Qt.Key_Down)\n    assert widget.list_widget.currentItem().text() == \"dog\"\n\n    # key press to enter label\n    qtbot.keyPress(widget, QtCore.Qt.Key_P)\n    qtbot.keyPress(widget, QtCore.Qt.Key_E)\n    qtbot.keyPress(widget, QtCore.Qt.Key_R)\n    qtbot.keyPress(widget, QtCore.Qt.Key_S)\n    qtbot.keyPress(widget, QtCore.Qt.Key_O)\n    qtbot.keyPress(widget, QtCore.Qt.Key_N)\n    assert widget.text() == \"person\"\n\n\n@pytest.mark.gui\ndef test_LabelDialog_addLabelHistory(qtbot):\n    labels = [\"cat\", \"dog\", \"person\"]\n    widget = LabelDialog(labels=labels, sort_labels=True)\n    qtbot.addWidget(widget)\n\n    widget.addLabelHistory(\"bicycle\")\n    assert widget.labelList.count() == 4\n    widget.addLabelHistory(\"bicycle\")\n    assert widget.labelList.count() == 4\n    item: QtWidgets.QListWidgetItem | None = widget.labelList.item(0)\n    assert item\n    assert item.text() == \"bicycle\"\n\n\n@pytest.mark.gui\ndef test_LabelDialog_popUp(qtbot):\n    labels = [\"cat\", \"dog\", \"person\"]\n    widget = LabelDialog(labels=labels, sort_labels=True)\n    qtbot.addWidget(widget)\n\n    # popUp(text='cat')\n\n    def interact():\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_P)  # enter 'p' for 'person'  # NOQA\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n\n    QtCore.QTimer.singleShot(500, interact)\n    label, flags, group_id, description = widget.popUp(\"cat\")\n    assert label == \"person\"\n    assert flags == {}\n    assert group_id is None\n    assert description == \"\"\n\n    # popUp()\n\n    def interact():\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n\n    QtCore.QTimer.singleShot(500, interact)\n    label, flags, group_id, description = widget.popUp()\n    assert label == \"person\"\n    assert flags == {}\n    assert group_id is None\n    assert description == \"\"\n\n    # popUp() + key_Up\n\n    def interact():\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Up)  # 'person' -> 'dog'  # NOQA\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n        qtbot.keyClick(widget.edit, QtCore.Qt.Key_Enter)  # NOQA\n\n    QtCore.QTimer.singleShot(500, interact)\n    label, flags, group_id, description = widget.popUp()\n    assert label == \"dog\"\n    assert flags == {}\n    assert group_id is None\n    assert description == \"\"\n"
  },
  {
    "path": "tests/unit/widgets/label_list_widget_test.py",
    "content": "import pytest\n\nfrom labelme.widgets import LabelListWidget\nfrom labelme.widgets import LabelListWidgetItem\n\n\n@pytest.mark.gui\ndef test_LabelListWidget(qtbot):\n    widget = LabelListWidget()\n\n    item = LabelListWidgetItem(text=\"person <font color='red'>●</fon>\")\n    widget.addItem(item)\n    item = LabelListWidgetItem(text=\"dog <font color='blue'>●</fon>\")\n    widget.addItem(item)\n\n    widget.show()\n    qtbot.addWidget(widget)\n    qtbot.waitExposed(widget)\n"
  },
  {
    "path": "tools/update_translate.py",
    "content": "import re\nimport subprocess\nimport sys\nfrom pathlib import Path\n\nfrom loguru import logger\n\nhere: Path = Path(__file__).parent\n\n\ndef main():\n    logger.remove(0)\n    logger.level(\"INFO\", color=\"<dim><white>\")\n    logger.add(\n        sys.stderr,\n        level=\"INFO\",\n        colorize=True,\n        format=\"<level>{message}</level>\",\n        backtrace=False,\n        diagnose=False,\n    )\n\n    labelme_path: Path = here / \"..\" / \"labelme\"\n    labelme_files: list[Path] = list(labelme_path.rglob(\"*.py\"))\n\n    labelme_translate_path: Path = labelme_path / \"translate\"\n\n    pylupdate_version: str = (\n        subprocess.check_output([\"pylupdate5\", \"-version\"], stderr=subprocess.STDOUT)\n        .decode()\n        .split()[-1]\n        .lstrip(\"v\")\n    )\n    logger.info(\"using pylupdate5 version: {}\", pylupdate_version)\n    if pylupdate_version.split(\".\")[:2] != [\"5\", \"15\"]:\n        logger.warning(\"pylupdate5 version is not 5.15.x, skipping .ts generation\")\n        return\n\n    lrelease_version: str = (\n        subprocess.check_output([\"lrelease\", \"-version\"]).decode().split()[-1]\n    )\n    logger.info(\"using lrelease version: {}\", lrelease_version)\n    if lrelease_version.split(\".\")[:2] != [\"5\", \"15\"]:\n        logger.warning(\"lrelease version is not 5.15.x, skipping .qm generation\")\n        return\n\n    languages: list[str] = sorted(\n        [ts_file.stem for ts_file in labelme_translate_path.glob(\"*.ts\")]\n    )\n    for lang in languages:\n        ts_path: Path = labelme_translate_path / f\"{lang}.ts\"\n        subprocess.check_call(\n            [\n                \"pylupdate5\",\n                \"-noobsolete\",\n                *labelme_files,\n                \"-ts\",\n                str(ts_path),\n            ]\n        )\n        assert ts_path.exists()\n\n        # Zero out line numbers to reduce unnecessary diffs in .ts file\n        ts_content: str = ts_path.read_text()\n        new_ts_content: str = re.sub(r'line=\"\\d+\"', 'line=\"0\"', ts_content)\n        assert ts_content.strip() != new_ts_content.strip()\n        ts_path.write_text(new_ts_content)\n        logger.info(\"updated .ts file: {}\", ts_path)\n\n        qm_path: Path = labelme_translate_path / f\"{lang}.qm\"\n        subprocess.check_call(\n            [\"lrelease\", ts_path, \"-qm\", qm_path],\n            stdout=subprocess.DEVNULL,\n            stderr=subprocess.DEVNULL,\n        )\n        assert qm_path.exists()\n        logger.info(\"updated .qm file: {}\", qm_path)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  }
]