/**
 * @openapi
 *  components:
 *  schemas:
 *    CrowdinFiles:
 *      type: array
 *      description: 'List of Crowdin files and folders'
 *      example: [{id: '1', name: 'Landing pages'}, {id: '2', parentId: '1', name: 'Home Page', type: 'json'}]
 *      items:
 *        anyOf:
 *          - type: object
 *            description: 'Folder'
 *            properties:
 *              id:
 *                type: string
 *                description: 'Unique identifier'
 *              name:
 *                type: string
 *                description: 'Folder name'
 *              parentId:
 *                type: string
 *                description: 'Parent folder identifier'
 *          - type: object
 *            description: 'File'
 *            properties:
 *              id:
 *                type: string
 *                description: 'Unique identifier'
 *              parentId:
 *                type: string
 *                description: 'Parent folder identifier'
 *              name:
 *                type: string
 *                description: 'File name'
 *              type:
 *                type: string
 *                description: 'File type (e.g., json, xml, html)'
 *              excludedTargetLanguages:
 *                type: array
 *                description: 'Languages excluded from translation'
 *                items:
 *                  type: string
 *    NodeType:
 *      type: string
 *      description: 'Type of tree element'
 *      enum:
 *        - '0'
 *        - '1'
 *        - '2'
 *      x-enum-descriptions:
 *        - 'Folder'
 *        - 'File'
 *        - 'Branch'
 *    IntegrationFiles:
 *      type: array
 *      description: 'List of integration files and folders'
 *      items:
 *        anyOf:
 *          - type: object
 *            description: 'Folder'
 *            properties:
 *              id:
 *                type: string
 *                description: 'Unique identifier'
 *              name:
 *                type: string
 *                description: 'Folder name'
 *              parentId:
 *                type: string
 *                description: 'Parent folder identifier'
 *              path:
 *                type: string
 *                description: 'Full path to the folder'
 *              createdAt:
 *                type: string
 *                format: date-time
 *                description: 'Folder creation timestamp (ISO 8601)'
 *              updatedAt:
 *                type: string
 *                format: date-time
 *                description: 'Folder last update timestamp (ISO 8601)'
 *          - type: object
 *            description: 'File'
 *            properties:
 *              id:
 *                type: string
 *                description: 'Unique identifier'
 *              name:
 *                type: string
 *                description: 'File name'
 *              parentId:
 *                type: string
 *                description: 'Parent folder identifier'
 *              type:
 *                type: string
 *                description: 'File type (e.g., json, xml, html)'
 *              path:
 *                type: string
 *                description: 'Full path to the file'
 *              createdAt:
 *                type: string
 *                format: date-time
 *                description: 'File creation timestamp (ISO 8601)'
 *              updatedAt:
 *                type: string
 *                format: date-time
 *                description: 'File last update timestamp (ISO 8601)'
 *              isNew:
 *                type: boolean
 *                description: 'Whether file is new (created after last sync)'
 *              isUpdated:
 *                type: boolean
 *                description: 'Whether file was updated since last sync'
 *              notSynced:
 *                type: boolean
 *                description: 'Whether file was never synced to Crowdin'
 *              synced:
 *                type: boolean
 *                description: 'Whether file was previously synced to Crowdin'
 *    UpdateCrowdinFiles:
 *      title: 'Sync Files to Crowdin'
 *      required:
 *        - projectId
 *        - files
 *      properties:
 *        projectId:
 *          description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *          type: integer
 *          example: 12
 *        files:
 *          $ref: '#/components/schemas/IntegrationFiles'
 *        uploadTranslations:
 *          description: 'Upload exist translation from integration'
 *          type: boolean
 *          default: false
 *          example: true
 *    FileLanguagePair:
 *      title: 'Sync Translations to Integration'
 *      required:
 *        - projectId
 *        - files
 *      properties:
 *        projectId:
 *          description: 'Project Id. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *          type: integer
 *          example: 12
 *        files:
 *          example: { 102: ['de', 'fr'], 999: ['uk'] }
 *          type: object
 *          description: |
 *            - **{fileId}** _(integer)_: Crowdin File Id. Get via [List Crowdin Files](#operation/crowdin.files)
 *            - **[{languageCode}]** _(array of strings)_: List Of  Language Id. Get via [List Supported Languages](https://support.crowdin.com/developer/api/v2/#tag/Languages/operation/api.languages.getMany)
 *
 *            **Example:**
 *              ```json
 *              {
 *               102: ["de", "fr"],
 *               999: ["uk"]
 *              }
 *              ```
 *    UpdateResponse:
 *      type: object
 *      properties:
 *        jobId:
 *          type: string
 *          example: '067da473-fc0b-43e3-b0a2-09d26af130c1'
 *    SettingsData:
 *      type: object
 *      description: 'Application configuration settings. Fields depend on integration implementation.'
 *      additionalProperties: true
 *      example:
 *        schedule: '3'
 *        condition: '1'
 *        new-crowdin-files: true
 *        new-integration-files: false
 *        inContext: false
 *        importEqSuggestions: true
 *        autoApproveImported: false
 *        translateHidden: false
 *        includeByFilePath: '/content/**'
 *        excludeByFilePath: '/drafts/**'
 *    UpdateSettingsData:
 *      title: 'Update Application Settings'
 *      required:
 *        - projectId
 *        - config
 *      properties:
 *        projectId:
 *          description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *          type: integer
 *          example: 12
 *        config:
 *          $ref: '#/components/schemas/SettingsData'
 *    SettingsResponse:
 *      $ref: '#/components/schemas/SettingsData'
 *    SettingsSchemaResponse:
 *      type: array
 *      description: 'List of configuration fields with metadata'
 *      items:
 *        type: object
 *        properties:
 *          key:
 *            type: string
 *            description: 'Unique field identifier'
 *            example: 'schedule'
 *          label:
 *            type: string
 *            description: 'Human-readable field label'
 *            example: 'Sync schedule'
 *          labelHtml:
 *            type: string
 *            description: 'HTML label (alternative to label)'
 *          type:
 *            type: string
 *            enum: [checkbox, text, select, textarea, notice, password, file]
 *            description: 'Field input type'
 *            example: 'select'
 *          defaultValue:
 *            type: string
 *            description: 'Default value for the field'
 *            example: '0'
 *          helpText:
 *            type: string
 *            description: 'Plain text help description'
 *          helpTextHtml:
 *            type: string
 *            description: 'HTML help description'
 *          category:
 *            type: string
 *            description: 'Field category (general, sync, advanced)'
 *            example: 'sync'
 *          position:
 *            type: integer
 *            description: 'Display order within category'
 *            example: 0
 *          options:
 *            type: array
 *            description: 'Available options (for select type)'
 *            items:
 *              type: object
 *              properties:
 *                value:
 *                  type: string
 *                label:
 *                  type: string
 *          dependencySettings:
 *            type: string
 *            description: 'JSON string defining field visibility rules'
 *          isSearchable:
 *            type: boolean
 *            description: 'Allow searching options (for select type)'
 *          isMulti:
 *            type: boolean
 *            description: 'Allow multiple selection (for select type)'
 *          noticeType:
 *            type: string
 *            enum: [info, warning, danger, success]
 *            description: 'Notice type (for notice type fields)'
 *          noIcon:
 *            type: boolean
 *            description: 'Hide icon in notice (for notice type)'
 *    CrowdinSyncSettingsResponse:
 *      type: object
 *      description: 'Mapping of Crowdin file IDs to target language codes for auto-sync'
 *      additionalProperties:
 *        type: array
 *        description: 'Array of language codes to sync for this file'
 *        items:
 *          type: string
 *          description: 'Language code (e.g., uk, de, fr)'
 *      example:
 *        '102': ['uk', 'de', 'fr']
 *        '999': ['uk', 'es']
 *    IntegrationSyncSettingsResponse:
 *      type: array
 *      description: 'List of integration files configured for auto-sync with their current status'
 *      items:
 *        type: object
 *        required:
 *          - id
 *          - name
 *          - node_type
 *        properties:
 *          id:
 *            type: string
 *            description: 'Unique file identifier'
 *          name:
 *            type: string
 *            description: 'File name'
 *          parent_id:
 *            type: string
 *            description: 'Parent folder identifier'
 *          type:
 *            type: string
 *            description: 'File type (e.g., html, json)'
 *          node_type:
 *            $ref: '#/components/schemas/NodeType'
 *          schedule:
 *            type: boolean
 *            description: 'Whether auto-sync is enabled for this file'
 *          sync:
 *            type: boolean
 *            description: 'Sync status flag'
 *          isNew:
 *            type: boolean
 *            description: 'Whether file is new (created after last sync)'
 *          isUpdated:
 *            type: boolean
 *            description: 'Whether file was updated since last sync'
 *          notSynced:
 *            type: boolean
 *            description: 'Whether file was never synced to Crowdin'
 *          synced:
 *            type: boolean
 *            description: 'Whether file was previously synced to Crowdin'
 *    UpdateSyncSettingsData:
 *      title: 'Update Auto-Sync Files Configuration'
 *      required:
 *        - projectId
 *        - provider
 *        - files
 *      properties:
 *        projectId:
 *          description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *          type: integer
 *          example: 12
 *        provider:
 *          type: string
 *          description: 'Sync direction: "crowdin" for Crowdin→Integration, "integration" for Integration→Crowdin'
 *          enum:
 *            - crowdin
 *            - integration
 *        files:
 *          description: 'Format depends on provider. For "crowdin" - object with fileId→languages mapping. For "integration" - array of file objects.'
 *          oneOf:
 *            - $ref: '#/components/schemas/CrowdinSyncSettingsResponse'
 *            - $ref: '#/components/schemas/IntegrationSyncSettingsResponse'
 *    FileProgress:
 *      title: 'Language Translation Progress'
 *      description: 'Language Translation File Progress Response Model'
 *      type: object
 *      properties:
 *        languageId:
 *          type: string
 *          example: af
 *        eTag:
 *          type: string
 *          example: fd0ea167420ef1687fd16635b9fb67a3
 *        language:
 *          type: object
 *          description: 'Complete language information'
 *          nullable: true
 *          properties:
 *            id:
 *              type: string
 *              example: uk
 *            name:
 *              type: string
 *              example: Ukrainian
 *            editorCode:
 *              type: string
 *              example: uk
 *            twoLettersCode:
 *              type: string
 *              example: uk
 *            threeLettersCode:
 *              type: string
 *              example: ukr
 *            locale:
 *              type: string
 *              example: uk-UA
 *            androidCode:
 *              type: string
 *              example: uk-rUA
 *            osxCode:
 *              type: string
 *              example: uk.lproj
 *            osxLocale:
 *              type: string
 *              example: uk
 *            pluralCategoryNames:
 *              type: array
 *              items:
 *                type: string
 *              example: ['one', 'few', 'many', 'other']
 *            pluralRules:
 *              type: string
 *              example: '((n%10==1 && n%100!=11) ? 0 : ...)'
 *            pluralExamples:
 *              type: array
 *              items:
 *                type: string
 *              example: ['1, 21, 31...', '2-4, 22-24...']
 *            textDirection:
 *              type: string
 *              enum: [ltr, rtl]
 *              example: ltr
 *            dialectOf:
 *              type: string
 *              nullable: true
 *              example: null
 *        words:
 *          properties:
 *            total:
 *              type: integer
 *              example: 7249
 *            translated:
 *              type: integer
 *              example: 3651
 *            preTranslateAppliedTo:
 *              type: integer
 *              example: 0
 *            approved:
 *              type: integer
 *              example: 3637
 *          type: object
 *        phrases:
 *          properties:
 *            total:
 *              type: integer
 *              example: 3041
 *            translated:
 *              type: integer
 *              example: 2631
 *            preTranslateAppliedTo:
 *              type: integer
 *              example: 0
 *            approved:
 *              type: integer
 *              example: 2622
 *          type: object
 *        translationProgress:
 *          type: string
 *          example: '86'
 *        approvalProgress:
 *          type: string
 *          example: '86'
 *        qaChecksStatus:
 *          type: object
 *          description: 'QA checks status information'
 *          properties:
 *            total:
 *              type: integer
 *              example: 0
 *            inProgress:
 *              type: integer
 *              example: 0
 *            passed:
 *              type: integer
 *              example: 0
 *            failed:
 *              type: integer
 *              example: 0
 *    LoginFieldsResponse:
 *      type: object
 *      properties:
 *        fields:
 *          type: array
 *          items:
 *            type: object
 *            properties:
 *              key:
 *                type: string
 *                description: 'Unique field identifier'
 *                example: 'apiKey'
 *              name:
 *                type: string
 *                description: 'Human-readable field label'
 *                example: 'Service API key'
 *              type:
 *                type: string
 *                description: 'Field input type'
 *                enum:
 *                  - text
 *                  - password
 *                  - checkbox
 *                  - select
 *                  - textarea
 *                  - file
 *                  - notice
 *                example: 'password'
 *              options:
 *                type: array
 *                description: 'Available options (only for select type)'
 *                items:
 *                  type: object
 *                  properties:
 *                    label:
 *                      type: string
 *                    value:
 *                      type: string
 *      example:
 *        fields: [{ key: 'email', name: 'User email', type: 'text' }, { key: 'password', name: 'User password', type: 'password' }]
 *    Login:
 *      title: 'Login'
 *      required:
 *        - projectId
 *        - credentials
 *      properties:
 *        projectId:
 *          description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *          type: integer
 *          example: 12
 *        credentials:
 *          $ref: '#/components/schemas/LoginData'
 *    LoginData:
 *      type: object
 *      description: 'Login Form Fields. Get via [Integration Login Form Fields](#operation/integration.fields)'
 *      example: { email: 'user@crowdin.com', password: 'password' }
 *    JobStatus:
 *      type: string
 *      description: 'Possible job statuses'
 *      enum:
 *        - created
 *        - inProgress
 *        - finished
 *        - failed
 *        - canceled
 *    JobType:
 *      type: string
 *      description: 'Possible job types'
 *      enum:
 *        - updateCrowdin
 *        - updateIntegration
 *        - crowdinSyncSettingsSave
 *        - integrationSyncSettingsSave
 *    JobListItem:
 *      type: object
 *      description: 'Job item returned in list response'
 *      properties:
 *        id:
 *          type: string
 *          description: 'Unique identifier of the job'
 *          example: '067da473-fc0b-43e3-b0a2-09d26af130c1'
 *        progress:
 *          type: integer
 *          description: 'Current progress percentage (0-100)'
 *          minimum: 0
 *          maximum: 100
 *          example: 94
 *        status:
 *          $ref: '#/components/schemas/JobStatus'
 *        title:
 *          type: string
 *          description: 'Human-readable title of the job'
 *          example: 'Sync files to Crowdin'
 *        type:
 *          $ref: '#/components/schemas/JobType'
 *        createdAt:
 *          type: string
 *          format: date-time
 *          description: 'ISO 8601 timestamp when the job was created'
 *          example: '2024-01-15T10:30:00.000Z'
 *        finishedAt:
 *          type: string
 *          format: date-time
 *          nullable: true
 *          description: 'ISO 8601 timestamp when the job finished (null if not finished)'
 *          example: '2024-01-15T10:35:00.000Z'
 *    Job:
 *      type: object
 *      description: 'Detailed job information'
 *      properties:
 *        id:
 *          type: string
 *          description: 'Unique identifier of the job'
 *          example: '067da473-fc0b-43e3-b0a2-09d26af130c1'
 *        progress:
 *          type: integer
 *          description: 'Current progress percentage (0-100)'
 *          minimum: 0
 *          maximum: 100
 *          example: 94
 *        status:
 *          $ref: '#/components/schemas/JobStatus'
 *        title:
 *          type: string
 *          description: 'Human-readable title of the job'
 *          example: 'Sync files to Crowdin'
 *        type:
 *          $ref: '#/components/schemas/JobType'
 *        info:
 *          type: string
 *          nullable: true
 *          description: 'Additional information about the job progress (e.g., ETA)'
 *          example: 'About 2 minutes remaining'
 *        data:
 *          type: object
 *          nullable: true
 *          description: 'Additional data associated with the job'
 *        payload:
 *          type: object
 *          nullable: true
 *          description: 'Original payload used to create the job'
 *        attempt:
 *          type: integer
 *          nullable: true
 *          description: 'Current attempt number for retried jobs'
 *          example: 1
 *        eta:
 *          type: number
 *          nullable: true
 *          description: 'Estimated time remaining in milliseconds'
 *          example: 120000
 *        createdAt:
 *          type: string
 *          format: date-time
 *          description: 'ISO 8601 timestamp when the job was created'
 *          example: '2024-01-15T10:30:00.000Z'
 *        updatedAt:
 *          type: string
 *          format: date-time
 *          nullable: true
 *          description: 'ISO 8601 timestamp when the job was last updated'
 *          example: '2024-01-15T10:32:00.000Z'
 *        finishedAt:
 *          type: string
 *          format: date-time
 *          nullable: true
 *          description: 'ISO 8601 timestamp when the job finished'
 *          example: '2024-01-15T10:35:00.000Z'
 *    JobListResponse:
 *      type: object
 *      description: 'List of jobs response'
 *      properties:
 *        data:
 *          type: array
 *          items:
 *            $ref: '#/components/schemas/JobListItem'
 *    JobInfoResponse:
 *      type: object
 *      description: 'Single job info response'
 *      properties:
 *        data:
 *          $ref: '#/components/schemas/Job'
 *    ErrorResponse:
 *      type: object
 *      properties:
 *        error:
 *          type: object
 *          properties:
 *            message:
 *              type: string
 *              description: 'Error message describing what went wrong'
 *              example: 'jobId is required'
 *    JobBasic:
 *      type: object
 *      deprecated: true
 *      description: 'Basic job info (deprecated format)'
 *      properties:
 *        id:
 *          type: string
 *          description: 'The Unique Identifier For The Job.'
 *          example: '067da473-fc0b-43e3-b0a2-09d26af130c1'
 *        progress:
 *          type: integer
 *          description: 'The Progress Of The Job.'
 *          example: 94
 *        status:
 *          type: string
 *          description: 'The Current Status Of The Job.'
 *          example: 'inProgress'
 *        title:
 *          type: string
 *          description: 'The Title Of The Job.'
 *          example: 'Sync files to Crowdin'
 *    JobResponse:
 *      type: object
 *      deprecated: true
 *      description: 'Deprecated. Use Job or JobListResponse instead'
 *      properties:
 *        data:
 *          type: array
 *          items:
 *            $ref: '#/components/schemas/JobBasic'
 *
 *  parameters:
 *    ProjectId:
 *      name: projectId
 *      in: query
 *      description: 'Project Identifier. Get via [List Projects](https://developer.crowdin.com/api/v2/#operation/api.projects.getMany)'
 *      required: true
 *      schema:
 *        type: integer
 *        example: 12
 *
 *  securitySchemes:
 *    bearerAuth:
 *      type: http
 *      scheme: bearer
 *      description: 'Crowdin API Personal Access Token. Get via [Account Settings](https://crowdin.com/settings#api-key)'
 */
