[
  {
    "path": ".codebeatsettings",
    "content": "{\n  \"SWIFT\": {\n    \"TOO_MANY_FUNCTIONS\": [50, 100, 150, 200],\n    \"TOTAL_LOC\": [200, 400, 500, 600]\n  }\n}"
  },
  {
    "path": ".gitattributes",
    "content": "*.sh linguist-language=Swift\n*.podspec linguist-language=Swift\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [juanpe]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: \"\\U0001F41B Bug report\"\nabout: Report a bug or unexpected behavior while using SkeletonView\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n### Description\n\nDescribe your issue here.\n\n### What type of issue is this? (place an `x` in one of the `[ ]`)\n- [ ] bug\n- [ ] enhancement (feature request)\n- [ ] question\n- [ ] documentation related\n- [ ] discussion\n\n### Requirements (place an `x` in each of the `[ ]`)\n* [ ] I've read and understood the [Contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md) and have done my best effort to follow them.\n* [ ] I've read and agree to the [Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md).\n* [ ] I've searched for any related issues and avoided creating a duplicate issue.\n\n---\n\n### Bug Report\n\nFilling out the following details about bugs will help us solve your issue sooner.\n\n### SkeletonView Environment:\n\n**SkeletonView version:**\n**Xcode version:**\n**Swift version:**\n\n#### Steps to reproduce:\n\n*Please replace this with the steps to reproduce the behavior.*\n\n1.\n2.\n3.\n\n#### Expected result:\n\n*Please replace this with what you expected to happen.*\n\n#### Actual result:\n\n*Please replace this with of what happened instead.*  \n\n#### Attachments:\n\nLogs, screenshots, sample project, funny gif, etc.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feedback.md",
    "content": "---\nname: \"\\U0001F4E3 Feedback\"\nabout: Give us general feedback about the SkeletonView\ntitle: ''\nlabels: feedback\nassignees: ''\n\n---\n\n# SkeletonView Feedback\n\nYou can use this template to give us structured feedback or just wipe it and leave us a note. Thank you!\n\n## What have you loved?\n\n_eg \"the nice colors\"_\n\n## What was confusing or gave you pause?\n\n_eg \"it did something unexpected\"_\n\n## Are there features you'd like to see added?\n\n_eg \"SkeletonView should be compatible with SwiftUI\"_\n\n## Anything else?\n\n_eg \"have a nice day\"_\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/submit-a-request.md",
    "content": "---\nname: \"⭐ Submit a request\"\nabout: Surface a feature or problem that you think should be solved\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n### Describe the feature or problem you’d like to solve\n\nA clear and concise description of what the feature or problem is.\n\n### Proposed solution\n\nHow will it benefit SkeletonView and its users?\n\n### Additional context\n\nAdd any other context like screenshots or mockups are helpful, if applicable.\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "### Summary\n\nDescribe the goal of this PR. Mention any related Issue numbers.\n\n### Requirements (place an `x` in each of the `[ ]`)\n* [ ] I've read and understood the [Contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md) and have done my best effort to follow them.\n* [ ] I've read and agree to the [Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md).\n"
  },
  {
    "path": ".github/release-drafter.yml",
    "content": "name-template: '📦 $RESOLVED_VERSION'\ntag-template: '$RESOLVED_VERSION'\ncategory-template: '#### $TITLE'\nchange-template: '- **#$NUMBER**: $TITLE - @$AUTHOR'\ntemplate: |\n  $CHANGES\ncategories:\n  - title: '🚨 Breaking'\n    label: 'breaking'\n  - title: '🔬Improvements'\n    label: '💡 enhancement'\n  - title: '🙌 New'\n    label: 'feature'\n  - title: '🩹 Bug fixes'\n    label: '🐞 bug'\n  - title: '⚙️ Maintenance'\n    label: '⚙️ maintenance'\n  - title: '📚 Documentation'\n    label: '📚 docs'\n  - title: '💾 Dependency Updates'\n    label: 'dependencies'\n\nversion-resolver:\n  major:\n    labels:\n      - 'breaking'\n  minor:\n    labels:\n      - '💡 enhancement'\n      - 'feature'\n  patch:\n    labels:\n      - '🐞 bug'\n      - '⚙️ maintenance'\n      - '📚 docs'\n      - 'dependencies'\n\nexclude-labels:\n  - 'skip-changelog'\n"
  },
  {
    "path": ".github/workflows/CD.yml",
    "content": "name: CD\n\non:\n  pull_request_target:\n    branches: [main]\n    types: [closed]\n        \njobs:\n  release_version:\n    if: github.event.pull_request.milestone == null && github.event.pull_request.merged == true\n    runs-on: macOS-latest\n    steps:\n      - uses: actions/checkout@v2\n            \n      - name: Publish release\n        id: publish_release\n        uses: release-drafter/release-drafter@v5\n        with: \n          publish: true\n        env:\n           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Update podspec \n        run: fastlane bump_version next_version:${{ steps.publish_release.outputs.tag_name }}\n\n      - name: Commit changes\n        uses: stefanzweifel/git-auto-commit-action@v4\n        with:\n          branch: 'main'\n          commit_message: 'Bump version ${{ steps.publish_release.outputs.tag_name }}'\n        env:\n         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}   \n\n      - name: Deploy to Cocoapods\n        continue-on-error: true\n        env:\n          COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}\n        run: |\n          set -eo pipefail\n          pod lib lint --allow-warnings\n          pod trunk push --allow-warnings    \n\n      - name: Tweet the release\n        uses: ethomson/send-tweet-action@v1\n        with:\n          consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}\n          consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}\n          access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}\n          access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}\n          status: |\n            🎉 New release ${{ steps.publish_release.outputs.tag_name }} is out 🚀\n\n            Check out all the changes here: \n            ${{ steps.publish_release.outputs.html_url }} \n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\n\non:\n  pull_request:\n    branches: [main]\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: macos-latest\n    strategy:\n      matrix:\n        build-config:    \n          - { scheme: 'SkeletonView iOS', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }\n          - { scheme: 'SkeletonView tvOS', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }\n          - { scheme: 'iOS Example', destination: 'platform=iOS Simulator,name=iPhone 8', sdk: 'iphonesimulator' }\n          - { scheme: 'tvOS Example', destination: 'platform=tvOS Simulator,name=Apple TV', sdk: 'appletvsimulator' }\n    steps:\n      - uses: actions/checkout@v2\n      - name: Build\n        run: xcodebuild clean build -workspace 'SkeletonView.xcworkspace' -scheme '${{ matrix.build-config['scheme'] }}' -sdk '${{ matrix.build-config['sdk'] }}' -destination '${{ matrix.build-config['destination'] }}'\n\n"
  },
  {
    "path": ".github/workflows/needs-attention.yml",
    "content": "name: Issue Needs Attention\n# This workflow is triggered on issue comments.\non:\n  issue_comment:\n    types: created\n\njobs:\n  applyNeedsAttentionLabel:\n    name: Apply Needs Attention Label\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Apply Needs Attention Label\n        uses: hramos/needs-attention@v1\n        with:\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n          response-required-label: 'awaiting user info'\n          needs-attention-label: 'needs triage'\n"
  },
  {
    "path": ".github/workflows/pod_lib_lint.yml",
    "content": "name: Pod lint\non: [workflow_dispatch]\n        \njobs:\n  pod_lib_lint:\n    runs-on: macOS-latest\n    steps:\n      - uses: actions/checkout@v2\n   \n      - env:\n          COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}\n        run: |\n          set -eo pipefail\n          pod lib lint --allow-warnings         \n"
  },
  {
    "path": ".github/workflows/pod_trunk.yml",
    "content": "name: Pod trunk\non: [workflow_dispatch]\n        \njobs:\n  release_version:\n    runs-on: macOS-latest\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Deploy to Cocoapods\n        env:\n          COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}\n        run: |\n          set -eo pipefail\n          pod lib lint --allow-warnings\n          pod trunk push --allow-warnings  \n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\non: [workflow_dispatch]\n        \njobs:\n  release_version:\n    runs-on: macOS-latest\n    steps:\n      - uses: actions/checkout@v2\n          \n      - name: Publish release\n        id: publish_release\n        uses: release-drafter/release-drafter@v5\n        with: \n          publish: true\n        env:\n           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Update podspec \n        run: fastlane bump_version next_version:${{ steps.publish_release.outputs.tag_name }}\n\n      - name: Commit changes\n        uses: stefanzweifel/git-auto-commit-action@v4\n        with:\n          branch: 'main'\n          commit_message: 'Bump version ${{ steps.publish_release.outputs.tag_name }}'\n        env:\n         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}      \n\n      - name: Deploy to Cocoapods\n        env:\n          COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}\n        run: |\n          set -eo pipefail\n          pod lib lint --allow-warnings\n          pod trunk push --allow-warnings  \n          \n      - name: Tweet the release\n        uses: ethomson/send-tweet-action@v1\n        with:\n          consumer-key: ${{ secrets.TWITTER_CONSUMER_API_KEY }}\n          consumer-secret: ${{ secrets.TWITTER_CONSUMER_API_SECRET }}\n          access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }}\n          access-token-secret: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}\n          status: |\n            🎉 New release ${{ steps.publish_release.outputs.tag_name }} is out 🚀\n            Check out all the changes here: \n            ${{ steps.publish_release.outputs.html_url }} \n"
  },
  {
    "path": ".github/workflows/release_notes.yml",
    "content": "name: Release Notes\n\non:\n  push:\n    branches:\n      - main\n\njobs:\n  update_release_notes:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: release-drafter/release-drafter@master\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: 'Close stale issues and PRs'\non:\n  schedule:\n    - cron: '30 5 * * *'\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v4\n        with:\n          close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.'\n          stale-issue-message: '🤖 This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions 🙂'\n          days-before-stale: 5\n          days-before-close: 3\n          enable-statistics: true\n          operations-per-run: 60\n          only-labels: 'awaiting user input'"
  },
  {
    "path": ".github/workflows/validations.yml",
    "content": "name: Validations\n\non: \n  pull_request_target:\n    branches: [main]\n    types: [opened, reoneped, edited, synchronized]\n\n#  workflow_dispatch:\n#    inputs:\n#      commit hash:\n#        description: \"Commit hash\"\n#        required: true\n#        default: \"\"\n\njobs:\n  lint:\n    runs-on: macos-latest\n    steps:\n      - uses: actions/checkout@v2 \n      - name: Run SwiftLint\n        run: swiftlint lint --reporter github-actions-logging\n\n  danger: \n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Danger\n        uses: docker://frmeloni/danger-swift-with-swiftlint:1.3.1\n        with:\n            args: --failOnErrors --verbose\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          \n          \n"
  },
  {
    "path": ".gitignore",
    "content": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData/\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata/\n\n## Other\n*.moved-aside\n*.xccheckout\n*.xcscmblueprint\n.DS_Store\n\n## Obj-C/Swift specific\n*.hmap\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n# Package.pins\n.build/\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\nPods/\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the\n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\n\n# JetBrains\n\n.idea\n"
  },
  {
    "path": ".swift-version",
    "content": "5.0\n"
  },
  {
    "path": ".swiftlint.yml",
    "content": "included:\n  - SkeletonViewCore/Sources\ndisabled_rules:\n  - trailing_whitespace\n  - line_length\n  - type_body_length\n  - identifier_name\n  - multiple_closures_with_trailing_closure\n  - class_delegate_protocol\n  - force_unwrapping\n  - force_try\n  - force_cast\n  - function_parameter_count\n  - discouraged_optional_collection\n  - shorthand_operator\n  - reduce_boolean\n  - weak_delegate\n  - nesting\n  - closure_end_indentation \n  - function_default_parameter_at_end\n  - unowned_variable_capture\n  - legacy_constructor\n  - redundant_type_annotation\n  - vertical_whitespace_opening_braces\nopt_in_rules:\n  - multiline_arguments\n  - multiline_parameters\n  - closure_spacing\n  - closure_body_length\n  - collection_alignment\n  - contains_over_filter_is_empty\n  - contains_over_filter_count\n  - contains_over_first_not_nil\n  - contains_over_range_nil_comparison\n  - convenience_type\n  - discouraged_object_literal\n  - discouraged_optional_boolean\n  - empty_count\n  - empty_string\n  - fallthrough\n  - file_name_no_space\n  - first_where\n  - flatmap_over_map_reduce\n  - implicitly_unwrapped_optional\n  - joined_default_parameter\n  - last_where\n  - literal_expression_end_indentation\n  - multiline_function_chains\n  - operator_usage_whitespace\n  - private_action\n  - private_outlet\n  - redundant_optional_initialization\n  - redundant_set_access_control\n  - sorted_first_last\n  - switch_case_on_newline\n  - unneeded_parentheses_in_closure_argument\n  - unused_declaration\n  - unused_import\n  - discouraged_optional_collection\n  - enum_case_associated_values_count\n  - legacy_multiple\n  - legacy_random\nindentation: 2\ntype_name:\n    min_length: 2\n    max_length:\n        warning: 50\n        error: 60\nfile_length:\n - 2500\n - 3000\nlarge_tuple:\n - 5\n - 6"
  },
  {
    "path": ".swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file\n\n### Next version\n\n#### 🙌 New\n\n#### 🔬 Improvements\n* [**369**](https://github.com/Juanpe/SkeletonView/pull/369): remove useless corner radius constraint - [@Juanpe](https://github.com/Juanpe)\n* [**357**](https://github.com/Juanpe/SkeletonView/pull/357): Removed duplicate code in SkeletonCollectionDelegate. - [@keshavamurthy1](https://github.com/keshavamurthy1)\n  \n#### 🩹 Bug fixes\n* [**359**](https://github.com/Juanpe/SkeletonView/pull/359): SkeletonView respecting Font's height, rather than the `UIView` actual height. - [@keshavamurthy1](https://github.com/keshavamurthy1)\n\n\n## 📦 [1.11.0](https://github.com/Juanpe/SkeletonView/releases/tag/1.11.0)\n\n#### 🙌 New\n* [**339**](https://github.com/Juanpe/SkeletonView/pull/339): Add `hiddenWhenSkeletonIsActive` property - [@mohn93](https://github.com/mohn93)\n* [**341**](https://github.com/Juanpe/SkeletonView/pull/341): Support autoreverses in gradient animations - [@Juanpe](https://github.com/Juanpe)\n\n#### 🔬Improvements\n* [**344**](https://github.com/Juanpe/SkeletonView/pull/344): Resize labels based on number of lines - [@Juanpe](https://github.com/Juanpe)\n\n#### 🩹 Bug fixes\n* [**340**](https://github.com/Juanpe/SkeletonView/pull/340): Fixed incorrect padding, and incorrect multiline layer frame calculation - [@yzhao198](https://github.com/yzhao198)\n\n## 📦 [1.10.0](https://github.com/Juanpe/SkeletonView/releases/tag/1.10.0)\n\n#### 🙌 New\n* [**327**](https://github.com/Juanpe/SkeletonView/pull/327): Add SwiftLint - [@Juanpe](https://github.com/Juanpe)\n* [**329**](https://github.com/Juanpe/SkeletonView/pull/329): Spanish README 🇪🇸 - [@Juanpe](https://github.com/Juanpe)\n\n#### 🩹 Bug fixes\n* [**336**](https://github.com/Juanpe/SkeletonView/pull/336): Not replace text when the skeleton disappears. Solved issues: [#296](https://github.com/Juanpe/SkeletonView/issues/296), [#330](https://github.com/Juanpe/SkeletonView/issues/330) - [@Juanpe](https://github.com/Juanpe)\n* [**337**](https://github.com/Juanpe/SkeletonView/pull/337): RTL support. Solved issues: [#143](https://github.com/Juanpe/SkeletonView/issues/143) - [@Juanpe](https://github.com/Juanpe)\n\n## 📦 [1.9](https://github.com/Juanpe/SkeletonView/releases/tag/1.9)\n\n#### 🩹 Bug fixes\n* [**319**](https://github.com/Juanpe/SkeletonView/pull/319): Fix to consider the top and bottom edge insets when updating the skeleton layer height - [@xpereta](https://github.com/xpereta)\n* [**320**](https://github.com/Juanpe/SkeletonView/pull/320): Fix Single line customisation - [@Juanpe](https://github.com/juanpe)\n* [**323**](https://github.com/Juanpe/SkeletonView/pull/323): Save and restore view state for UIButton - [@Juanpe](https://github.com/juanpe)\n\n## 📦 [1.8.8](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.8)\n\n#### 🙌 New\n* [**304**](https://github.com/Juanpe/SkeletonView/pull/304): French README 🇫🇷 - [@OmarJalil](https://github.com/OmarJalil)\n\n#### 🔬Improvements\n* [**311**](https://github.com/Juanpe/SkeletonView/pull/311): Bump json from 2.2.0 to 2.3.1 - [@dependabot](https://github.com/dependabot)\n\n#### 🩹 Bug fixes\n* [**286**](https://github.com/Juanpe/SkeletonView/pull/286): Fix issue when WKWebView calls skeletonLayoutSubviews not on the main thread - [@paulanatoleclaudot-betclic](https://github.com/paulanatoleclaudot-betclic)\n* [**292**](https://github.com/Juanpe/SkeletonView/pull/292): Fix IBInspectable support when using Carthage - [@marisalaneous](https://github.com/marisalaneous)\n* [**308**](https://github.com/Juanpe/SkeletonView/pull/308): Fix example backgroundColor in DarkMode - [@toshi0383](https://github.com/toshi0383)\n* [**307**](https://github.com/Juanpe/SkeletonView/pull/307): Prevent incorrect skeletonLayer to be added when updating skeleton - [@wsalim1610](https://github.com/wsalim1610)\n\n## 📦 [1.8.7](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.7)\n\n#### 🔬Improvements\n* [**271**](https://github.com/Juanpe/SkeletonView/pull/271): Add corner radius for skeletonView as IBInspectable (CGFloat) default is 0.0 - [@paulanatoleclaudot-betclic](https://github.com/paulanatoleclaudot-betclic)\n\n#### 🩹 Bug fixes\n* [**259**](https://github.com/Juanpe/SkeletonView/issues/259): Prevent isSkeletonActive to be called when isSkeletonable is false - [@wsalim1610](https://github.com/wsalim1610)\n* [**274**](https://github.com/Juanpe/SkeletonView/pull/274): Fix: hiding skeleton when header and footer views of section would not hide it - [@darkside999](https://github.com/darkside999)\n* [**273**](https://github.com/Juanpe/SkeletonView/pull/273): Fix: in vertical stack view with center alignment show incorrect position - [@koooootake](https://github.com/koooootake)\n\n## 📦 [1.8.6](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.6)\n\n#### 🔬Improvements\n* [**242**](https://github.com/Juanpe/SkeletonView/pull/242): Offscreen table view layout issue fixed - [@Cacodemon](https://github.com/Cacodemon)\n* [**261**](https://github.com/Juanpe/SkeletonView/pull/261): Fixes removing skeleton layers from table header footer sections - [@darkside999](https://github.com/darkside999)\n* [**263**](https://github.com/Juanpe/SkeletonView/pull/263): Feature/set cross dissolve transitions as default - [@Juanpe](https://github.com/Juanpe)\n* [**264**](https://github.com/Juanpe/SkeletonView/pull/264): not replace original datasource is running XCTests - [@Juanpe](https://github.com/Juanpe)\n* [**265**](https://github.com/Juanpe/SkeletonView/pull/265): call original traitCollectionDidChange method - [@Juanpe](https://github.com/Juanpe)\n\n#### 🩹 Bug fixes\n* [**260**](https://github.com/Juanpe/SkeletonView/issues/260): Don't hide skeleton layers on TableViewHeaderFooterView\n* [**257**](https://github.com/Juanpe/SkeletonView/issues/257): Unit test problem when using SkeletonView\n\n\n## 📦 [1.8.3](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.3)\n\n- Support for iOS 13 dark mode. (thanks @Wilsonator5000)\n\n## 📦 [1.8.2](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.2)\n\n#### 🙌 New\n- Add ability to customize line spacing per label. (thanks @gshahbazian)\n\n## 📦 [LayoutSkeleton (1.8.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.8.1)\n\n#### 🔬Improvements\n- Fix completion call in .none transition style while hide skeletons. (thanks @aadudyrev)\n\n#### 🙌 New\n- Swizzle `layoutSubviews` method.\n\n#### 🔬Improvements\n- Fix completion call in .none transition style while hiding skeletons. (thanks @aadudyrev)\n- Swift format.\n\n#### 🩹 Bug fixes\n- Update layout subviews when the original method is called.\n   - Issues: [#88, #149]\n\n## 📦 [Transitions (1.8)](https://github.com/Juanpe/SkeletonView/releases/tag/1.8)\n\n#### 🙌 New\n\n- Adding swift news to mentioned section (thanks @osterbergmarcus).\n- Create `SkeletonTransitionStyle`. Now, you can animate transition when you show or hide skeletons. (thanks @pontusjacobsson)\n\n#### 🔬Improvements\n- Refactor some methods.\n\n#### 🩹 Bug fixes\n- Solved issues.\n [#175](https://github.com/Juanpe/SkeletonView/issues/175) Swift Package Manager version format\n\n## 📦 [Layout update (1.7)](https://github.com/Juanpe/SkeletonView/releases/tag/1.7)\n\n#### 🙌 New\n\n- Allow updating skeleton layout to recalculate skeleton bounds: `layoutSkeletonIfNeeded`. See the examples to know how to use it. (thanks @eduardbosch)\n\n#### 🔬Improvements\n\n- Allow updating skeleton layers without recreating them: `updateSkeleton`, `updateGradientSkeleton`, `updateAnimatedSkeleton`, `updateAnimatedGradientSkeleton`. (thanks @eduardbosch)\n\n## 📦 [Debug (1.4)](https://github.com/Juanpe/SkeletonView/releases/tag/1.4)\n\n#### 🙌 New\n\n- Create `skeletonDescription` print a skeleton representation of the view.\n- Create `SKELETON_DEBUG` environment variable, in order to print the view hierarchy when the skeleton appears.\n\n#### 🔬Improvements\n- Add two new methods to `SkeletonFlowDelegate` protocol. Now you can know when the skeleton did show and when it did hide.\n- `Recursive` protocol\n\n#### 🩹 Bug fixes\n- Solved issue [#86](https://github.com/Juanpe/SkeletonView/issues/86) (thanks @reececomo)\n\n## 📦 [Custom defaults (1.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.3)\n\n#### 🙌 New\n\n- Default values customizables. Now you can set the default values of Skeleton appearance.(thanks @reececomo)\n  - issues: [[#50](https://github.com/Juanpe/SkeletonView/issues/50), [#83](https://github.com/Juanpe/SkeletonView/issues/83)]\n\n#### 🩹 Bug fixes\n- Solved issue [#41](https://github.com/Juanpe/SkeletonView/issues/41). Now, Skeleton works if UICollectionView cell's Nib is registered in code. (thanks @kjoneandrei)\n\n## 📦 [Typo (1.2.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.3)\n\n####  Fixes\n\n- Fix typo in `SkeletonTableViewDataSource` protocol\n\n#### 🔬Improvements\n\n- Now it takes in account the `UIStackView` to calculate the `SkeletonLayer` bounds (thanks @giantramen)\n\n## 📦 [New face (1.2.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.2)\n\n#### 🙌 New\n\n- Rebranding\n\n#### 🩹 Bug fixes\n- Solved issue [#23](https://github.com/Juanpe/SkeletonView/issues/23). Problem with UIStackView. (thanks @giantramen)\n\n## 📦 [State (1.2.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2.1)\n\n#### 🙌 New\n\n- You can set the corner radius multiline elements (thanks @B4V4-G)\n- Save view state when skeleton appears and recovery when it is hidden (@juanpe)\n\n#### 🩹 Bug fixes\n- Solved issue [#51](https://github.com/Juanpe/SkeletonView/issues/51). Support inspectable properties when using Carthage. (thanks @eduardbosch)\n\n## 📦 [On TV (1.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.2)\n\n#### 🙌 New\n- Now ```SkeletonView``` is **tvOS** compatible! 🎉.  (thanks @mihai8804858)\n\n#### 🩹 Bug fixes\n- Solved issue [#46](https://github.com/Juanpe/SkeletonView/issues/46). It crashes the application when tap on it, didSelect called and crash.\n\n\n## 📦 [Hotfix (1.1.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.1.1)\n\n#### 🩹 Bug fixes\n- Now yes, solved issue [#39](https://github.com/Juanpe/SkeletonView/issues/39)\n\n## 📦 [Needed (1.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.1)\n\n#### 🙌 New\n- Now ```SkeletonView```supports **UICollectionViews**! 🎉.  (thanks @Renatdz)\n\n#### 🩹 Bug fixes\n- Solved issue [#39](https://github.com/Juanpe/SkeletonView/issues/39). Gradient animation did not work when app becomes active.\n\n\n## 📦 [Resizable (1.0.5)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.5)\n\n#### 🙌 New\n- Now you can use table views with resizable cells.\n\n#### 🩹 Bug fixes\n- Solved issues.\n [#17](https://github.com/Juanpe/SkeletonView/issues/17),\n [#30](https://github.com/Juanpe/SkeletonView/issues/30),\n [#34](https://github.com/Juanpe/SkeletonView/issues/34).\n\n## 📦 [Filled or not (1.0.4)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.4)\n\n#### 🙌 New\n- You can set the filling percent of the last line in multiline elements (thanks @jontelang!)\n\n#### 🩹 Bug fixes\n- Solved issue [#14](https://github.com/Juanpe/SkeletonView/issues/14). You could edit text views with skeleton active.\n\n## 📦 [In all directions (1.0.3)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.3)\n\n#### 🙌 New\n- Create ```SkeletonAnimationBuilder```, to facilitate the creation of layer animations.\n```GradientDirection``` enum.\n\n## 📦 [Retro (1.0.2)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)\n\n#### 🙌 New\n- Change some private keywords, to be Swift 3 compatible\n\n## 📦 [Early bird bug (1.0.1)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0.2)\n\n#### 🩹 Bug fixes\n- It was not removing the skeleton layer\n\n## 📦 [Starter (1.0)](https://github.com/Juanpe/SkeletonView/releases/tag/1.0)\n\n- First release\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nThe Code of Conduct governs how we behave in public or in private\nwhenever the project will be judged by our actions.\nWe expect it to be honored by everyone who represents the project\nofficially or informally,\nclaims affiliation with the project,\nor participates directly.\n\nWe strive to:\n\n* **Be open**: We invite anybody to participate in any aspect of our projects.\n  Our community is open, and any responsibility can be carried\n  by any contributor who demonstrates the required capacity and competence.\n* **Be empathetic**: We work together to resolve conflict,\n  assume good intentions,\n  and do our best to act in an empathic fashion.\n  By understanding that humanity drops a few packets in online interactions,\n  and adjusting accordingly,\n  we can create a comfortable environment for everyone to share their ideas.\n* **Be collaborative**: We prefer to work transparently\n  and to involve interested parties early on in the process.\n  Wherever possible, we work closely with others in the open source community\n  to coordinate our efforts.\n* **Be decisive**: We expect participants in the project to resolve disagreements constructively.\n  When they cannot, we escalate the matter to structures\n  with designated leaders to arbitrate and provide clarity and direction.\n* **Be responsible**: We hold ourselves accountable for our actions.\n  When we make mistakes, we take responsibility for them.\n  When we need help, we reach out to others.\n  When it comes time to move on from a project,\n  we take the proper steps to ensure that others can pick up where we left off.\n\nThis code is not exhaustive or complete.\nIt serves to distill our common understanding of a\ncollaborative, shared environment and goals.\nWe expect it to be followed in spirit as much as in the letter.\n\n---\n\nThe **SkeletonView** Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributors Guide\n\nInterested in contributing? Awesome! Before you do though, please read our\n[Code of Conduct](https://github.com/Juanpe/SkeletonView/blob/main/CODE_OF_CONDUCT.md). We take it very seriously, and expect that you will as\nwell.\n\nThere are many ways you can contribute! :heart:\n\n### Bug Reports and Fixes :bug:\n-  If you find a bug, please search for it in the [Issues](https://github.com/Juanpe/SkeletonView/issues), and if it isn't already tracked,\n   [create a new issue](https://github.com/slackhq/PanModal/issues/new). Fill out the \"Bug Report\" section of the issue template. Even if an Issue is closed, feel free to comment and add details, it will still\n   be reviewed.\n-  Issues that have already been identified as a bug (note: able to reproduce) will be labelled `🐞 Bug`.\n-  If you'd like to submit a fix for a bug, [send a Pull Request](#creating_a_pull_request) and mention the Issue number.\n\n### New Features :bulb:\n-  If you'd like to add new functionality to this project, describe the problem you want to solve in a [new Issue](https://github.com/Juanpe/SkeletonView/issues/new).\n-  Issues that have been identified as a feature request will be labelled `💡 Enhancement`.\n-  If you'd like to implement the new feature, please wait for feedback from the project\n   maintainers before spending too much time writing the code. In some cases, `💡 Enhancement`s may\n   not align well with the project objectives at the time.\n\n### Miscellaneous :sparkles:\n-  If you have an alternative implementation of something that may have advantages over the way its currently\n   done, or you have any other change, we would be happy to hear about it!\n  -  If its a trivial change, go ahead and [send a Pull Request](#creating_a_pull_request) with the changes you have in mind.\n  -  If not, [open an Issue](https://github.com/Juanpe/SkeletonView/issues/new) to discuss the idea first.\n\nIf you're new to our project and looking for some way to make your first contribution, look for\nIssues labelled `good first issue`.\n\n## Requirements\n\nFor your contribution to be accepted:\n\n- [x] The changes must be approved by code review.\n- [x] Commits should be atomic and messages must be descriptive. Related issues should be mentioned by Issue number.\n\nIf the contribution doesn't meet the above criteria, you may fail our automated checks or a maintainer will discuss it with you. You can continue to improve a Pull Request by adding commits to the branch from which the PR was created.\n\n## Creating a Pull Request\n\n1.  :fork_and_knife: Fork the repository on GitHub.\n2.  :runner: Clone/fetch your fork to your local development machine.\n3.  :herb: Create a new branch and check it out.\n4.  :crystal_ball: Make your changes and commit them locally.\n5.  :arrow_heading_up: Push your new branch to your fork. (e.g. `git push username fix-issue-300`).\n6.  :inbox_tray: Open a Pull Request on github.com from your new branch on your fork to `main` in this\n    repository.\n\n## Developer's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n- (a) The contribution was created in whole or in part by me and I\n      have the right to submit it under the open source license\n      indicated in the file; or\n\n- (b) The contribution is based upon previous work that, to the best\n      of my knowledge, is covered under an appropriate open source\n      license and I have the right under that license to submit that\n      work with modifications, whether created in whole or in part\n      by me, under the same open source license (unless I am\n      permitted to submit under a different license), as indicated\n      in the file; or\n\n- (c) The contribution was provided directly to me by some other\n      person who certified (a), (b) or (c) and I have not modified\n      it.\n\n- (d) I understand and agree that this project and the contribution\n      are public and that a record of the contribution (including all\n      personal information I submit with it, including my sign-off) is\n      maintained indefinitely and may be redistributed consistent with\n      this project or the open source license(s) involved.\n\n*Wording of statement copied from [elinux.org](http://elinux.org/Developer_Certificate_Of_Origin)*\n"
  },
  {
    "path": "Dangerfile.swift",
    "content": "import Danger\n\nlet danger = Danger()\nlet github = danger.github\n\n // Make it more obvious that a PR is a work in progress and shouldn't be merged yet\nif danger.github.pullRequest.title.contains(\"WIP\") {\n    warn(\"PR is classed as Work in Progress\")\n}\n\n// Warn, asking to update all README files if only English README are updated\nlet enReameModified = danger.git.modifiedFiles.contains { $0.contains(\"README.md\") }\nlet zhReameModified = danger.git.modifiedFiles.contains { $0.contains(\"README_zh.md\") }\nlet koReameModified = danger.git.modifiedFiles.contains { $0.contains(\"README_ko.md\") }\nlet ptBrReameModified = danger.git.modifiedFiles.contains { $0.contains(\"README_pt-br.md\") }\nlet otherLanguagesReadmeHaveBeenModified = zhReameModified && koReameModified && ptBrReameModified\n\nif (enReameModified && !otherLanguagesReadmeHaveBeenModified) {\n    warn(\"Consider **also** updating the README for other languages.\")\n}\n\n// Warn when there is a big PR\nif (danger.github.pullRequest.additions ?? 0) > 500 {\n    warn(\"Big PR, try to keep changes smaller if you can\")\n}\n\n// Added (or removed) library files need to be added (or removed) from the\n// Xcode project to avoid breaking things.\nlet addedSwiftLibraryFiles = danger.git.createdFiles.contains { $0.fileType == .swift && $0.hasPrefix(\"Sources\") }\nlet deletedSwiftLibraryFiles = danger.git.deletedFiles.contains { $0.fileType == .swift && $0.hasPrefix(\"Sources\") }\nlet modifiedXcodeProject = danger.git.modifiedFiles.contains { $0.contains(\".xcodeproj\") }\nif (addedSwiftLibraryFiles || deletedSwiftLibraryFiles) && !modifiedXcodeProject {\n    fail(\"Added or removed files require the Xcode project to be updated.\")\n}\n"
  },
  {
    "path": "Examples/CollectionView/AppDelegate.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Examples/CollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/CollectionView/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/CollectionView/Assets.xcassets/avatar.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"avatar.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/CollectionView/Assets.xcassets/picture.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"picture.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/CollectionView/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" systemVersion=\"17A277\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Examples/CollectionView/CollectionViewCell.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\nimport SkeletonView\n\nclass CollectionViewCell: UICollectionViewCell {\n    \n    var label: UILabel!\n    var imageView: UIImageView!\n    \n    override init(frame: CGRect) {\n        super.init(frame: frame)\n        \n        isSkeletonable = true\n        createLabel()\n        createImageView()\n        \n    }\n    \n    required init?(coder aDecoder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n    \n    private func createImageView() {\n        imageView = UIImageView(image: UIImage(named: \"picture\"))\n        imageView.isSkeletonable = true\n        imageView.translatesAutoresizingMaskIntoConstraints = false\n        imageView.contentMode = .scaleAspectFit\n        addSubview(imageView)\n        NSLayoutConstraint.activate([\n            imageView.centerXAnchor.constraint(equalTo: centerXAnchor),\n            imageView.topAnchor.constraint(equalTo: topAnchor),\n            imageView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: 0.75),\n            imageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.75)\n            ])\n        \n        \n    }\n    \n    private func createLabel() {\n        label = UILabel()\n        label.isSkeletonable = true\n        label.text = \"Lorem ipsum\"\n        label.textAlignment = .center\n        label.translatesAutoresizingMaskIntoConstraints = false\n        addSubview(label)\n        NSLayoutConstraint.activate([\n            label.centerXAnchor.constraint(equalTo: centerXAnchor),\n            label.bottomAnchor.constraint(equalTo: bottomAnchor),\n            label.heightAnchor.constraint(equalToConstant: 40),\n            label.widthAnchor.constraint(equalToConstant: frame.width)\n            ])\n    }\n    \n}\n"
  },
  {
    "path": "Examples/CollectionView/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"15702\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"irH-dz-xqL\">\n    <device id=\"retina4_7\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"15704\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"qda-qV-vJk\">\n            <objects>\n                <viewController id=\"irH-dz-xqL\" customClass=\"ViewController\" customModule=\"SkeletonViewExampleUICollectionView\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Fso-nq-n6t\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"eHI-ka-8vS\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"243\"/>\n                                <subviews>\n                                    <textView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" textAlignment=\"natural\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"obr-b6-dib\">\n                                        <rect key=\"frame\" x=\"45\" y=\"142\" width=\"287\" height=\"78\"/>\n                                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" constant=\"78\" id=\"jx6-c1-U0j\"/>\n                                        </constraints>\n                                        <string key=\"text\">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </string>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                                        <textInputTraits key=\"textInputTraits\" autocapitalizationType=\"sentences\"/>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                            <userDefinedRuntimeAttribute type=\"number\" keyPath=\"lastLineFillPercent\">\n                                                <integer key=\"value\" value=\"40\"/>\n                                            </userDefinedRuntimeAttribute>\n                                        </userDefinedRuntimeAttributes>\n                                    </textView>\n                                    <imageView clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"scaleAspectFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"avatar\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ql9-Jy-aWM\">\n                                        <rect key=\"frame\" x=\"141\" y=\"20\" width=\"93\" height=\"93\"/>\n                                        <color key=\"backgroundColor\" red=\"0.56078431370000004\" green=\"0.59607843140000005\" blue=\"0.7843137255\" alpha=\"0.90709546230000004\" colorSpace=\"calibratedRGB\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" constant=\"93\" id=\"jlG-7K-wMd\"/>\n                                            <constraint firstAttribute=\"width\" constant=\"93\" id=\"xHX-Y1-dvi\"/>\n                                        </constraints>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                        </userDefinedRuntimeAttributes>\n                                    </imageView>\n                                </subviews>\n                                <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" relation=\"greaterThanOrEqual\" constant=\"243\" id=\"0g6-3g-uII\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"obr-b6-dib\" secondAttribute=\"trailing\" constant=\"43\" id=\"3ms-Wk-qcn\"/>\n                                    <constraint firstItem=\"obr-b6-dib\" firstAttribute=\"centerX\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"centerX\" constant=\"1\" id=\"B5s-DM-eR8\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"243\" id=\"GX5-3W-tUt\"/>\n                                    <constraint firstItem=\"Ql9-Jy-aWM\" firstAttribute=\"centerX\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"centerX\" id=\"HsA-ID-oSK\"/>\n                                    <constraint firstItem=\"Ql9-Jy-aWM\" firstAttribute=\"top\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"top\" constant=\"20\" id=\"Hxu-ae-hXQ\"/>\n                                    <constraint firstItem=\"obr-b6-dib\" firstAttribute=\"leading\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"leading\" constant=\"45\" id=\"eop-Gq-7mO\"/>\n                                    <constraint firstItem=\"obr-b6-dib\" firstAttribute=\"top\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"top\" constant=\"142\" id=\"inJ-75-hGX\"/>\n                                </constraints>\n                                <viewLayoutGuide key=\"safeArea\" id=\"36i-gK-pIa\"/>\n                                <userDefinedRuntimeAttributes>\n                                    <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                </userDefinedRuntimeAttributes>\n                            </view>\n                            <collectionView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" dataMode=\"prototypes\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HKL-L0-T2w\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"243\" width=\"375\" height=\"264\"/>\n                                <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <collectionViewFlowLayout key=\"collectionViewLayout\" minimumLineSpacing=\"10\" minimumInteritemSpacing=\"10\" id=\"mGU-kn-rfE\">\n                                    <size key=\"itemSize\" width=\"50\" height=\"50\"/>\n                                    <size key=\"headerReferenceSize\" width=\"0.0\" height=\"0.0\"/>\n                                    <size key=\"footerReferenceSize\" width=\"0.0\" height=\"0.0\"/>\n                                    <inset key=\"sectionInset\" minX=\"0.0\" minY=\"0.0\" maxX=\"0.0\" maxY=\"0.0\"/>\n                                </collectionViewFlowLayout>\n                                <cells/>\n                                <connections>\n                                    <outlet property=\"dataSource\" destination=\"irH-dz-xqL\" id=\"wya-hE-ovQ\"/>\n                                </connections>\n                            </collectionView>\n                            <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"JjA-MK-YzZ\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"507\" width=\"375\" height=\"160\"/>\n                                <subviews>\n                                    <segmentedControl opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"left\" contentVerticalAlignment=\"top\" segmentControlStyle=\"plain\" selectedSegmentIndex=\"0\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fMR-vj-7de\">\n                                        <rect key=\"frame\" x=\"20\" y=\"21\" width=\"145\" height=\"32\"/>\n                                        <segments>\n                                            <segment title=\"Solid\"/>\n                                            <segment title=\"Gradient\"/>\n                                        </segments>\n                                        <connections>\n                                            <action selector=\"changeSkeletonType:\" destination=\"irH-dz-xqL\" eventType=\"valueChanged\" id=\"lfR-JV-DU4\"/>\n                                        </connections>\n                                    </segmentedControl>\n                                    <switch opaque=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" on=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"KBe-RM-BG8\">\n                                        <rect key=\"frame\" x=\"308\" y=\"21\" width=\"51\" height=\"31\"/>\n                                        <connections>\n                                            <action selector=\"changeAnimated:\" destination=\"irH-dz-xqL\" eventType=\"valueChanged\" id=\"dlH-KK-iee\"/>\n                                        </connections>\n                                    </switch>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Animated\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GSj-Ze-UIK\">\n                                        <rect key=\"frame\" x=\"229\" y=\"26\" width=\"73\" height=\"21\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Color\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"4Hm-fj-45V\">\n                                        <rect key=\"frame\" x=\"20\" y=\"61\" width=\"41.5\" height=\"52\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                    <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HBJ-nh-56V\">\n                                        <rect key=\"frame\" x=\"69.5\" y=\"72\" width=\"30\" height=\"30\"/>\n                                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"width\" constant=\"30\" id=\"DVW-Tc-XEQ\"/>\n                                            <constraint firstAttribute=\"height\" constant=\"30\" id=\"JfP-3b-yqX\"/>\n                                        </constraints>\n                                    </view>\n                                    <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"aUR-Qo-gHK\">\n                                        <rect key=\"frame\" x=\"20\" y=\"61\" width=\"100\" height=\"52\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"width\" constant=\"100\" id=\"GvX-hq-2Qn\"/>\n                                            <constraint firstAttribute=\"height\" constant=\"52\" id=\"UQe-Cf-riE\"/>\n                                        </constraints>\n                                        <connections>\n                                            <action selector=\"btnChangeColorTouchUpInside:\" destination=\"irH-dz-xqL\" eventType=\"touchUpInside\" id=\"Xca-QC-htl\"/>\n                                        </connections>\n                                    </button>\n                                    <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" buttonType=\"roundedRect\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"nPs-17-vfs\">\n                                        <rect key=\"frame\" x=\"263\" y=\"72\" width=\"94\" height=\"30\"/>\n                                        <state key=\"normal\" title=\"Hide skeleton\"/>\n                                        <connections>\n                                            <action selector=\"showOrHideSkeleton:\" destination=\"irH-dz-xqL\" eventType=\"touchUpInside\" id=\"lHc-k2-OgV\"/>\n                                        </connections>\n                                    </button>\n                                    <stepper opaque=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" value=\"0.25\" maximumValue=\"5\" stepValue=\"0.25\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"3mz-9M-e7Q\">\n                                        <rect key=\"frame\" x=\"263\" y=\"123\" width=\"94\" height=\"32\"/>\n                                        <connections>\n                                            <action selector=\"transitionDurationStepperAction:\" destination=\"irH-dz-xqL\" eventType=\"valueChanged\" id=\"Ll0-Pr-d0V\"/>\n                                        </connections>\n                                    </stepper>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Fade Duration: 0.25 sec\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5gN-Jz-44y\">\n                                        <rect key=\"frame\" x=\"92.5\" y=\"130\" width=\"162.5\" height=\"18\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"15\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                </subviews>\n                                <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                <constraints>\n                                    <constraint firstItem=\"3mz-9M-e7Q\" firstAttribute=\"leading\" secondItem=\"5gN-Jz-44y\" secondAttribute=\"trailing\" constant=\"8\" id=\"65e-Nj-bKG\"/>\n                                    <constraint firstItem=\"HBJ-nh-56V\" firstAttribute=\"centerY\" secondItem=\"aUR-Qo-gHK\" secondAttribute=\"centerY\" id=\"81M-Wq-Avl\"/>\n                                    <constraint firstItem=\"fMR-vj-7de\" firstAttribute=\"leading\" secondItem=\"JjA-MK-YzZ\" secondAttribute=\"leading\" constant=\"20\" id=\"AyG-hI-tte\"/>\n                                    <constraint firstItem=\"aUR-Qo-gHK\" firstAttribute=\"leading\" secondItem=\"fMR-vj-7de\" secondAttribute=\"leading\" id=\"C1b-Hl-jEg\"/>\n                                    <constraint firstItem=\"3mz-9M-e7Q\" firstAttribute=\"trailing\" secondItem=\"nPs-17-vfs\" secondAttribute=\"trailing\" id=\"KuK-fc-jOQ\"/>\n                                    <constraint firstItem=\"nPs-17-vfs\" firstAttribute=\"centerY\" secondItem=\"aUR-Qo-gHK\" secondAttribute=\"centerY\" id=\"MQX-E5-IDE\"/>\n                                    <constraint firstItem=\"HBJ-nh-56V\" firstAttribute=\"leading\" secondItem=\"4Hm-fj-45V\" secondAttribute=\"trailing\" constant=\"8\" id=\"MhM-jY-LIA\"/>\n                                    <constraint firstItem=\"4Hm-fj-45V\" firstAttribute=\"height\" secondItem=\"aUR-Qo-gHK\" secondAttribute=\"height\" id=\"OSn-RA-wQL\"/>\n                                    <constraint firstItem=\"4Hm-fj-45V\" firstAttribute=\"leading\" secondItem=\"aUR-Qo-gHK\" secondAttribute=\"leading\" id=\"PwQ-UR-iMq\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"160\" id=\"QDV-wu-e3I\"/>\n                                    <constraint firstItem=\"5gN-Jz-44y\" firstAttribute=\"centerY\" secondItem=\"3mz-9M-e7Q\" secondAttribute=\"centerY\" id=\"TGP-Ep-0ob\"/>\n                                    <constraint firstItem=\"nPs-17-vfs\" firstAttribute=\"top\" secondItem=\"KBe-RM-BG8\" secondAttribute=\"bottom\" constant=\"20\" id=\"TPg-wY-9bc\"/>\n                                    <constraint firstItem=\"4Hm-fj-45V\" firstAttribute=\"centerY\" secondItem=\"aUR-Qo-gHK\" secondAttribute=\"centerY\" id=\"V4i-bF-Jed\"/>\n                                    <constraint firstItem=\"KBe-RM-BG8\" firstAttribute=\"leading\" secondItem=\"GSj-Ze-UIK\" secondAttribute=\"trailing\" constant=\"6\" id=\"ehg-tW-7kq\"/>\n                                    <constraint firstItem=\"GSj-Ze-UIK\" firstAttribute=\"centerY\" secondItem=\"KBe-RM-BG8\" secondAttribute=\"centerY\" id=\"esk-GV-DBS\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"KBe-RM-BG8\" secondAttribute=\"trailing\" constant=\"18\" id=\"hhE-rV-dV7\"/>\n                                    <constraint firstItem=\"KBe-RM-BG8\" firstAttribute=\"top\" secondItem=\"JjA-MK-YzZ\" secondAttribute=\"top\" constant=\"21\" id=\"pBQ-H8-xTK\"/>\n                                    <constraint firstAttribute=\"bottom\" secondItem=\"3mz-9M-e7Q\" secondAttribute=\"bottom\" constant=\"5\" id=\"pQ9-a6-hM4\"/>\n                                    <constraint firstItem=\"fMR-vj-7de\" firstAttribute=\"centerY\" secondItem=\"GSj-Ze-UIK\" secondAttribute=\"centerY\" id=\"q2v-t1-Zu0\"/>\n                                    <constraint firstAttribute=\"height\" relation=\"greaterThanOrEqual\" constant=\"160\" id=\"qR5-cz-YAm\"/>\n                                    <constraint firstItem=\"nPs-17-vfs\" firstAttribute=\"trailing\" secondItem=\"KBe-RM-BG8\" secondAttribute=\"trailing\" id=\"yls-k6-ZfC\"/>\n                                </constraints>\n                            </view>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                        <constraints>\n                            <constraint firstItem=\"eHI-ka-8vS\" firstAttribute=\"trailing\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"trailing\" id=\"0dc-Vd-yJY\"/>\n                            <constraint firstItem=\"JjA-MK-YzZ\" firstAttribute=\"leading\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"leading\" id=\"57i-UV-Wqd\"/>\n                            <constraint firstItem=\"eHI-ka-8vS\" firstAttribute=\"leading\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"leading\" id=\"5tt-Ne-67Y\"/>\n                            <constraint firstItem=\"JjA-MK-YzZ\" firstAttribute=\"bottom\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"bottom\" id=\"AAr-ke-R7M\"/>\n                            <constraint firstItem=\"JjA-MK-YzZ\" firstAttribute=\"trailing\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"trailing\" id=\"DtS-9c-zBC\"/>\n                            <constraint firstItem=\"HKL-L0-T2w\" firstAttribute=\"top\" secondItem=\"eHI-ka-8vS\" secondAttribute=\"bottom\" id=\"Jgf-jS-PLT\"/>\n                            <constraint firstItem=\"eHI-ka-8vS\" firstAttribute=\"top\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"top\" id=\"Ux2-GF-HLK\"/>\n                            <constraint firstItem=\"JjA-MK-YzZ\" firstAttribute=\"top\" secondItem=\"HKL-L0-T2w\" secondAttribute=\"bottom\" id=\"XEd-Gf-KFI\"/>\n                            <constraint firstItem=\"2Gq-Y8-1TU\" firstAttribute=\"trailing\" secondItem=\"HKL-L0-T2w\" secondAttribute=\"trailing\" id=\"bNo-98-pE4\"/>\n                            <constraint firstItem=\"HKL-L0-T2w\" firstAttribute=\"leading\" secondItem=\"2Gq-Y8-1TU\" secondAttribute=\"leading\" id=\"iIq-cx-paX\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"2Gq-Y8-1TU\"/>\n                        <userDefinedRuntimeAttributes>\n                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                        </userDefinedRuntimeAttributes>\n                    </view>\n                    <connections>\n                        <outlet property=\"avatarImage\" destination=\"Ql9-Jy-aWM\" id=\"VoL-by-ygR\"/>\n                        <outlet property=\"collectionView\" destination=\"HKL-L0-T2w\" id=\"HSe-j0-S5d\"/>\n                        <outlet property=\"colorSelectedView\" destination=\"HBJ-nh-56V\" id=\"Iiq-iY-Glj\"/>\n                        <outlet property=\"showOrHideSkeletonButton\" destination=\"nPs-17-vfs\" id=\"vw4-fW-QoD\"/>\n                        <outlet property=\"skeletonTypeSelector\" destination=\"fMR-vj-7de\" id=\"CgX-3A-weo\"/>\n                        <outlet property=\"switchAnimated\" destination=\"KBe-RM-BG8\" id=\"emU-g9-NHT\"/>\n                        <outlet property=\"transitionDurationLabel\" destination=\"5gN-Jz-44y\" id=\"69y-iR-mbi\"/>\n                        <outlet property=\"transitionDurationStepper\" destination=\"3mz-9M-e7Q\" id=\"tzK-W7-A4D\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"PkM-Y0-M5i\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-972\" y=\"-209.14542728635683\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"avatar\" width=\"215\" height=\"211\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Examples/CollectionView/SkeletonViewExampleCollectionview-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Examples/CollectionView/ViewController.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\nimport SkeletonView\n\nclass ViewController: UIViewController {\n    @IBOutlet weak var collectionView: UICollectionView! {\n        didSet {\n            collectionView.isSkeletonable = true\n            collectionView.backgroundColor = .clear\n            collectionView.showsHorizontalScrollIndicator = false\n            collectionView.showsVerticalScrollIndicator = false\n            \n            collectionView.dataSource = self\n            collectionView.delegate = self\n            \n            collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: \"CollectionViewCell\")\n        }\n    }\n    \n    @IBOutlet weak var avatarImage: UIImageView! {\n        didSet {\n            avatarImage.layer.cornerRadius = avatarImage.frame.width/2\n            avatarImage.layer.masksToBounds = true\n        }\n    }\n    \n    @IBOutlet weak var colorSelectedView: UIView! {\n        didSet {\n            colorSelectedView.layer.cornerRadius = 5\n            colorSelectedView.layer.masksToBounds = true\n            colorSelectedView.backgroundColor = SkeletonAppearance.default.tintColor\n        }\n    }\n    \n    @IBOutlet weak var switchAnimated: UISwitch!\n    @IBOutlet weak var skeletonTypeSelector: UISegmentedControl!\n    @IBOutlet weak var showOrHideSkeletonButton: UIButton!\n    @IBOutlet weak var transitionDurationLabel: UILabel!\n    @IBOutlet weak var transitionDurationStepper: UIStepper!\n    \n    var type: SkeletonType {\n        return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        transitionDurationStepper.value = 0.25\n        collectionView.prepareSkeleton(completion: { done in\n            self.view.showAnimatedSkeleton()\n        })\n    }\n    \n    @IBAction func changeAnimated(_ sender: Any) {\n        if switchAnimated.isOn {\n            view.startSkeletonAnimation()\n        } else {\n            view.stopSkeletonAnimation()\n        }\n    }\n    \n    @IBAction func changeSkeletonType(_ sender: Any) {\n        refreshSkeleton()\n    }\n    \n    @IBAction func btnChangeColorTouchUpInside(_ sender: Any) {\n        showAlertPicker()\n    }\n    \n    @IBAction func showOrHideSkeleton(_ sender: Any) {\n        showOrHideSkeletonButton.setTitle((view.isSkeletonActive ? \"Show skeleton\" : \"Hide skeleton\"), for: .normal)\n        view.isSkeletonActive ? hideSkeleton() : showSkeleton()\n    }\n    \n    @IBAction func transitionDurationStepperAction(_ sender: Any) {\n        transitionDurationLabel.text = \"transition duration: \\(transitionDurationStepper.value) sec\"\n    }\n    \n    func showSkeleton() {\n        refreshSkeleton()\n    }\n    \n    func hideSkeleton() {\n        view.hideSkeleton(transition: .crossDissolve(transitionDurationStepper.value))\n    }\n    \n    func refreshSkeleton() {\n        self.view.hideSkeleton()\n        if type == .gradient { showGradientSkeleton() }\n        else { showSolidSkeleton() }\n    }\n    \n    func showSolidSkeleton() {\n        if switchAnimated.isOn {\n            view.showAnimatedSkeleton(usingColor: colorSelectedView.backgroundColor!, transition: .crossDissolve(transitionDurationStepper.value))\n        } else {\n            view.showSkeleton(usingColor: colorSelectedView.backgroundColor!, transition: .crossDissolve(transitionDurationStepper.value))\n        }\n    }\n    \n    func showGradientSkeleton() {\n        let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)\n        if switchAnimated.isOn {\n            view.showAnimatedGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))\n        } else {\n            view.showGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))\n        }\n    }\n    \n    func showAlertPicker() {\n        let alertView = UIAlertController(title: \"Select color\", message: \"\\n\\n\\n\\n\\n\\n\", preferredStyle: .alert)\n        \n        let pickerView = UIPickerView(frame: CGRect(x: 0, y: 50, width: 260, height: 115))\n        pickerView.dataSource = self\n        pickerView.delegate = self\n        \n        alertView.view.addSubview(pickerView)\n        \n        let action = UIAlertAction(title: \"OK\", style: .default) { [unowned pickerView, unowned self] _ in\n            let row = pickerView.selectedRow(inComponent: 0)\n            self.colorSelectedView.backgroundColor = colors[row].0\n            self.refreshSkeleton()\n        }\n        alertView.addAction(action)\n        \n        let cancelAction = UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil)\n        alertView.addAction(cancelAction)\n        \n        present(alertView, animated: false, completion: {\n            pickerView.frame.size.width = alertView.view.frame.size.width\n        })\n    }\n}\n \n // MARK: - UIPickerViewDelegate, UIPickerViewDataSource\n\n extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {\n    func numberOfComponents(in pickerView: UIPickerView) -> Int {\n        return 1\n    }\n    \n    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {\n        return colors.count\n    }\n    \n    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {\n        return colors[row].1\n    }\n }\n\n// MARK: - UICollectionViewDelegateFlowLayout\n\nextension ViewController: UICollectionViewDelegateFlowLayout {\n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {\n        return CGSize(width: view.frame.width/3 - 10, height: view.frame.width/3 - 10)\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {\n        return 5\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {\n        return 5\n    }\n}\n\n// MARK: - SkeletonCollectionViewDataSource\n\nextension ViewController: SkeletonCollectionViewDataSource {\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier {\n        return \"CollectionViewCell\"\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return 10\n    }\n\n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell? {\n        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: \"CollectionViewCell\", for: indexPath) as? CollectionViewCell\n        cell?.isSkeletonable = indexPath.row != 0\n        return cell\n    }\n    \n    // MARK: - UICollectionViewDataSource\n    \n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        return 10\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: \"CollectionViewCell\", for: indexPath) as! CollectionViewCell\n        return cell\n    }\n\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath) {\n        let cell = cell as? CollectionViewCell\n        cell?.isSkeletonable = indexPath.row != 0\n    }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  SkeletonViewExample\n//\n//  Created by Juanpe Catalán on 02/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n    func applicationWillTerminate(_ application: UIApplication) {\n        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"color\" : {\n        \"platform\" : \"universal\",\n        \"reference\" : \"systemBlueColor\"\n      },\n      \"idiom\" : \"universal\"\n    },\n    {\n      \"appearances\" : [\n        {\n          \"appearance\" : \"luminosity\",\n          \"value\" : \"dark\"\n        }\n      ],\n      \"color\" : {\n        \"color-space\" : \"srgb\",\n        \"components\" : {\n          \"alpha\" : \"1.000\",\n          \"blue\" : \"1.000\",\n          \"green\" : \"1.000\",\n          \"red\" : \"1.000\"\n        }\n      },\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"76x76\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ipad\",\n      \"size\" : \"83.5x83.5\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"ios-marketing\",\n      \"size\" : \"1024x1024\",\n      \"scale\" : \"1x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/iOS Example/Sources/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Assets.xcassets/avatar.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"avatar.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Examples/iOS Example/Sources/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" systemVersion=\"17A277\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"19455\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"Va7-1y-Tel\">\n    <device id=\"retina5_9\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"19454\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"System colors in document resources\" minToolsVersion=\"11.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Item-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModule=\"iOS_Example\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"812\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"F9K-jU-100\" userLabel=\"ContainerView\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"44\" width=\"375\" height=\"243\"/>\n                                <subviews>\n                                    <textView clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" textAlignment=\"natural\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"e9V-mk-xH0\">\n                                        <rect key=\"frame\" x=\"45\" y=\"142\" width=\"287\" height=\"78\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" constant=\"78\" id=\"gF5-G1-lKI\"/>\n                                        </constraints>\n                                        <string key=\"text\">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </string>\n                                        <color key=\"textColor\" systemColor=\"labelColor\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                                        <textInputTraits key=\"textInputTraits\" autocapitalizationType=\"sentences\"/>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                            <userDefinedRuntimeAttribute type=\"number\" keyPath=\"lastLineFillPercent\">\n                                                <integer key=\"value\" value=\"40\"/>\n                                            </userDefinedRuntimeAttribute>\n                                            <userDefinedRuntimeAttribute type=\"number\" keyPath=\"linesCornerRadius\">\n                                                <integer key=\"value\" value=\"6\"/>\n                                            </userDefinedRuntimeAttribute>\n                                        </userDefinedRuntimeAttributes>\n                                    </textView>\n                                    <imageView clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"scaleAspectFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"avatar\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"nMj-pU-5wJ\">\n                                        <rect key=\"frame\" x=\"45\" y=\"20\" width=\"93\" height=\"93\"/>\n                                        <color key=\"backgroundColor\" red=\"0.56078431370000004\" green=\"0.59607843140000005\" blue=\"0.7843137255\" alpha=\"0.90709546230000004\" colorSpace=\"calibratedRGB\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" constant=\"93\" id=\"gw9-nu-cKo\"/>\n                                            <constraint firstAttribute=\"width\" constant=\"93\" id=\"zB6-Lp-IUt\"/>\n                                        </constraints>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                        </userDefinedRuntimeAttributes>\n                                    </imageView>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" numberOfLines=\"3\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"CJW-A4-Fb8\">\n                                        <rect key=\"frame\" x=\"166\" y=\"27\" width=\"166\" height=\"12\"/>\n                                        <color key=\"backgroundColor\" red=\"0.92156862750000001\" green=\"0.16862745100000001\" blue=\"0.54901960780000003\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"10\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                            <userDefinedRuntimeAttribute type=\"number\" keyPath=\"linesCornerRadius\">\n                                                <integer key=\"value\" value=\"5\"/>\n                                            </userDefinedRuntimeAttribute>\n                                            <userDefinedRuntimeAttribute type=\"number\" keyPath=\"skeletonLineSpacing\">\n                                                <real key=\"value\" value=\"8\"/>\n                                            </userDefinedRuntimeAttribute>\n                                        </userDefinedRuntimeAttributes>\n                                    </label>\n                                </subviews>\n                                <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\"/>\n                                <constraints>\n                                    <constraint firstItem=\"CJW-A4-Fb8\" firstAttribute=\"leading\" secondItem=\"nMj-pU-5wJ\" secondAttribute=\"trailing\" constant=\"28\" id=\"Drg-cD-6E8\"/>\n                                    <constraint firstItem=\"e9V-mk-xH0\" firstAttribute=\"leading\" secondItem=\"F9K-jU-100\" secondAttribute=\"leading\" constant=\"45\" id=\"HvQ-HY-zYU\"/>\n                                    <constraint firstItem=\"e9V-mk-xH0\" firstAttribute=\"centerX\" secondItem=\"F9K-jU-100\" secondAttribute=\"centerX\" constant=\"1\" id=\"KcB-tG-NXa\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"243\" id=\"MIj-xq-gr1\"/>\n                                    <constraint firstItem=\"nMj-pU-5wJ\" firstAttribute=\"leading\" secondItem=\"F9K-jU-100\" secondAttribute=\"leading\" constant=\"45\" id=\"TK6-Ws-2xY\"/>\n                                    <constraint firstItem=\"e9V-mk-xH0\" firstAttribute=\"top\" secondItem=\"F9K-jU-100\" secondAttribute=\"top\" constant=\"142\" id=\"Wcx-nZ-1lR\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"e9V-mk-xH0\" secondAttribute=\"trailing\" constant=\"43\" id=\"XbU-Og-rht\"/>\n                                    <constraint firstItem=\"CJW-A4-Fb8\" firstAttribute=\"top\" secondItem=\"F9K-jU-100\" secondAttribute=\"top\" constant=\"27\" id=\"ceh-gB-7Et\"/>\n                                    <constraint firstItem=\"nMj-pU-5wJ\" firstAttribute=\"top\" secondItem=\"F9K-jU-100\" secondAttribute=\"top\" constant=\"20\" id=\"hQL-cr-MaN\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"CJW-A4-Fb8\" secondAttribute=\"trailing\" constant=\"43\" id=\"nfT-a5-z36\"/>\n                                </constraints>\n                                <userDefinedRuntimeAttributes>\n                                    <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                </userDefinedRuntimeAttributes>\n                            </view>\n                            <tableView clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"plain\" separatorStyle=\"none\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UCB-SP-lQk\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"287\" width=\"375\" height=\"282\"/>\n                                <color key=\"separatorColor\" red=\"0.1061807256\" green=\"0.84678786989999999\" blue=\"0.031482450150000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                <prototypes>\n                                    <tableViewCell clipsSubviews=\"YES\" contentMode=\"scaleToFill\" preservesSuperviewLayoutMargins=\"YES\" selectionStyle=\"default\" indentationWidth=\"10\" reuseIdentifier=\"CellIdentifier\" rowHeight=\"120\" id=\"2dN-Bd-tdy\" customClass=\"Cell\" customModule=\"iOS_Example\" customModuleProvider=\"target\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"44.666666030883789\" width=\"375\" height=\"120\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" preservesSuperviewLayoutMargins=\"YES\" insetsLayoutMarginsFromSafeArea=\"NO\" tableViewCell=\"2dN-Bd-tdy\" id=\"7IN-F3-Mr6\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"120\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <subviews>\n                                                <imageView userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"avatar\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"oiE-tt-nc2\">\n                                                    <rect key=\"frame\" x=\"16\" y=\"18\" width=\"82\" height=\"82\"/>\n                                                    <color key=\"backgroundColor\" red=\"0.56078431370000004\" green=\"0.59607843140000005\" blue=\"0.7843137255\" alpha=\"0.90709546230000004\" colorSpace=\"calibratedRGB\"/>\n                                                    <constraints>\n                                                        <constraint firstAttribute=\"width\" constant=\"82\" id=\"4j0-PU-CmN\"/>\n                                                        <constraint firstAttribute=\"height\" constant=\"82\" id=\"iqE-Lc-FOj\"/>\n                                                    </constraints>\n                                                    <userDefinedRuntimeAttributes>\n                                                        <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                                    </userDefinedRuntimeAttributes>\n                                                </imageView>\n                                                <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"2\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"VhU-1t-AaI\" userLabel=\"Label\">\n                                                    <rect key=\"frame\" x=\"119\" y=\"29\" width=\"235\" height=\"20\"/>\n                                                    <color key=\"backgroundColor\" red=\"0.92156862750000001\" green=\"0.16862745100000001\" blue=\"0.54901960780000003\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                                                    <constraints>\n                                                        <constraint firstAttribute=\"height\" constant=\"20\" id=\"HRL-cI-ieC\"/>\n                                                    </constraints>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"15\"/>\n                                                    <nil key=\"textColor\"/>\n                                                    <nil key=\"highlightedColor\"/>\n                                                    <userDefinedRuntimeAttributes>\n                                                        <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                                        <userDefinedRuntimeAttribute type=\"number\" keyPath=\"linesCornerRadius\">\n                                                            <integer key=\"value\" value=\"5\"/>\n                                                        </userDefinedRuntimeAttribute>\n                                                        <userDefinedRuntimeAttribute type=\"number\" keyPath=\"lastLineFillPercent\">\n                                                            <integer key=\"value\" value=\"20\"/>\n                                                        </userDefinedRuntimeAttribute>\n                                                    </userDefinedRuntimeAttributes>\n                                                </label>\n                                                <textField opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"left\" contentVerticalAlignment=\"center\" borderStyle=\"roundedRect\" placeholder=\"placeholder\" textAlignment=\"natural\" minimumFontSize=\"17\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dha-bH-Ipf\">\n                                                    <rect key=\"frame\" x=\"119\" y=\"57\" width=\"235\" height=\"34\"/>\n                                                    <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"14\"/>\n                                                    <textInputTraits key=\"textInputTraits\"/>\n                                                    <userDefinedRuntimeAttributes>\n                                                        <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                                    </userDefinedRuntimeAttributes>\n                                                </textField>\n                                            </subviews>\n                                            <constraints>\n                                                <constraint firstItem=\"dha-bH-Ipf\" firstAttribute=\"top\" secondItem=\"VhU-1t-AaI\" secondAttribute=\"bottom\" constant=\"8\" symbolic=\"YES\" id=\"1Ek-1L-ZVs\"/>\n                                                <constraint firstItem=\"oiE-tt-nc2\" firstAttribute=\"leading\" secondItem=\"7IN-F3-Mr6\" secondAttribute=\"leadingMargin\" id=\"1be-ak-AH1\"/>\n                                                <constraint firstAttribute=\"bottom\" secondItem=\"oiE-tt-nc2\" secondAttribute=\"bottom\" constant=\"20\" id=\"CKt-oA-eBI\"/>\n                                                <constraint firstItem=\"oiE-tt-nc2\" firstAttribute=\"top\" secondItem=\"7IN-F3-Mr6\" secondAttribute=\"topMargin\" constant=\"7\" id=\"EKn-ST-LDX\"/>\n                                                <constraint firstAttribute=\"trailingMargin\" secondItem=\"VhU-1t-AaI\" secondAttribute=\"trailing\" constant=\"5\" id=\"I7C-Bq-mfK\"/>\n                                                <constraint firstItem=\"VhU-1t-AaI\" firstAttribute=\"leading\" secondItem=\"oiE-tt-nc2\" secondAttribute=\"trailing\" constant=\"21\" id=\"Ojr-Kz-1k6\"/>\n                                                <constraint firstItem=\"VhU-1t-AaI\" firstAttribute=\"top\" secondItem=\"7IN-F3-Mr6\" secondAttribute=\"topMargin\" constant=\"18\" id=\"ZW6-JY-S4c\"/>\n                                                <constraint firstItem=\"dha-bH-Ipf\" firstAttribute=\"trailing\" secondItem=\"VhU-1t-AaI\" secondAttribute=\"trailing\" id=\"baX-Nw-8sB\"/>\n                                                <constraint firstItem=\"dha-bH-Ipf\" firstAttribute=\"leading\" secondItem=\"VhU-1t-AaI\" secondAttribute=\"leading\" id=\"kzA-mV-IDt\"/>\n                                            </constraints>\n                                            <userDefinedRuntimeAttributes>\n                                                <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                            </userDefinedRuntimeAttributes>\n                                        </tableViewCellContentView>\n                                        <userDefinedRuntimeAttributes>\n                                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                                        </userDefinedRuntimeAttributes>\n                                        <connections>\n                                            <outlet property=\"avatar\" destination=\"oiE-tt-nc2\" id=\"Dkh-R5-Qhu\"/>\n                                            <outlet property=\"label1\" destination=\"VhU-1t-AaI\" id=\"kUW-HV-KrD\"/>\n                                            <outlet property=\"textField\" destination=\"dha-bH-Ipf\" id=\"OHI-6P-tuU\"/>\n                                        </connections>\n                                    </tableViewCell>\n                                </prototypes>\n                                <userDefinedRuntimeAttributes>\n                                    <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"NO\"/>\n                                </userDefinedRuntimeAttributes>\n                                <connections>\n                                    <outlet property=\"dataSource\" destination=\"BYZ-38-t0r\" id=\"Hxi-nC-gbY\"/>\n                                    <outlet property=\"delegate\" destination=\"BYZ-38-t0r\" id=\"Z10-Nx-iGb\"/>\n                                </connections>\n                            </tableView>\n                            <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"XgY-1a-UGc\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"569\" width=\"375\" height=\"160\"/>\n                                <subviews>\n                                    <segmentedControl opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"left\" contentVerticalAlignment=\"top\" segmentControlStyle=\"plain\" selectedSegmentIndex=\"0\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xOL-Sq-r4i\">\n                                        <rect key=\"frame\" x=\"20\" y=\"23\" width=\"145\" height=\"32\"/>\n                                        <segments>\n                                            <segment title=\"Solid\"/>\n                                            <segment title=\"Gradient\"/>\n                                        </segments>\n                                        <connections>\n                                            <action selector=\"changeSkeletonType:\" destination=\"BYZ-38-t0r\" eventType=\"valueChanged\" id=\"iAS-ab-0jP\"/>\n                                        </connections>\n                                    </segmentedControl>\n                                    <switch opaque=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" on=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"vz0-qg-GcZ\">\n                                        <rect key=\"frame\" x=\"308\" y=\"21\" width=\"51\" height=\"31\"/>\n                                        <connections>\n                                            <action selector=\"changeAnimated:\" destination=\"BYZ-38-t0r\" eventType=\"valueChanged\" id=\"w1G-gZ-RE0\"/>\n                                        </connections>\n                                    </switch>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Animated\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"WHN-wR-TKt\">\n                                        <rect key=\"frame\" x=\"229\" y=\"26\" width=\"73\" height=\"21\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Color\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7CF-rV-pK2\">\n                                        <rect key=\"frame\" x=\"20\" y=\"73.666666666666629\" width=\"90\" height=\"21\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                    <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"iGp-rp-t1d\">\n                                        <rect key=\"frame\" x=\"130\" y=\"69\" width=\"30\" height=\"30\"/>\n                                        <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"width\" constant=\"30\" id=\"Q3k-B1-E88\"/>\n                                            <constraint firstAttribute=\"height\" constant=\"30\" id=\"xOD-RY-U4u\"/>\n                                        </constraints>\n                                    </view>\n                                    <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Mde-Cm-CoS\">\n                                        <rect key=\"frame\" x=\"20\" y=\"58\" width=\"140\" height=\"52\"/>\n                                        <constraints>\n                                            <constraint firstAttribute=\"height\" constant=\"52\" id=\"3GX-2y-eQj\"/>\n                                            <constraint firstAttribute=\"width\" constant=\"140\" id=\"6cC-Y1-RKs\"/>\n                                        </constraints>\n                                        <connections>\n                                            <action selector=\"btnChangeColorTouchUpInside:\" destination=\"BYZ-38-t0r\" eventType=\"touchUpInside\" id=\"cB8-Ik-LIJ\"/>\n                                        </connections>\n                                    </button>\n                                    <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" buttonType=\"system\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Tdu-YQ-saq\">\n                                        <rect key=\"frame\" x=\"263\" y=\"69\" width=\"94\" height=\"30\"/>\n                                        <state key=\"normal\" title=\"Hide skeleton\"/>\n                                        <connections>\n                                            <action selector=\"showOrHideSkeleton:\" destination=\"BYZ-38-t0r\" eventType=\"touchUpInside\" id=\"Ma1-WX-Dzy\"/>\n                                        </connections>\n                                    </button>\n                                    <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Fade Duration: 0.25 sec\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mrw-PM-jJJ\">\n                                        <rect key=\"frame\" x=\"92.333333333333329\" y=\"130\" width=\"162.66666666666669\" height=\"18\"/>\n                                        <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"15\"/>\n                                        <nil key=\"textColor\"/>\n                                        <nil key=\"highlightedColor\"/>\n                                    </label>\n                                    <stepper opaque=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" value=\"0.25\" maximumValue=\"5\" stepValue=\"0.25\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"l4N-LL-ZrJ\">\n                                        <rect key=\"frame\" x=\"263\" y=\"123\" width=\"94\" height=\"32\"/>\n                                        <connections>\n                                            <action selector=\"transitionDurationStepperAction:\" destination=\"BYZ-38-t0r\" eventType=\"valueChanged\" id=\"jPN-df-fNs\"/>\n                                        </connections>\n                                    </stepper>\n                                </subviews>\n                                <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\"/>\n                                <constraints>\n                                    <constraint firstItem=\"l4N-LL-ZrJ\" firstAttribute=\"leading\" secondItem=\"mrw-PM-jJJ\" secondAttribute=\"trailing\" constant=\"8\" id=\"5iU-dO-qVc\"/>\n                                    <constraint firstItem=\"mrw-PM-jJJ\" firstAttribute=\"centerY\" secondItem=\"l4N-LL-ZrJ\" secondAttribute=\"centerY\" id=\"9OM-mx-4Jo\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"Tdu-YQ-saq\" secondAttribute=\"trailing\" constant=\"18\" id=\"BQ0-S0-YMp\"/>\n                                    <constraint firstItem=\"iGp-rp-t1d\" firstAttribute=\"trailing\" secondItem=\"Mde-Cm-CoS\" secondAttribute=\"trailing\" id=\"IJ3-CC-5M7\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"160\" id=\"OH5-ja-ZlB\"/>\n                                    <constraint firstItem=\"Mde-Cm-CoS\" firstAttribute=\"leading\" secondItem=\"XgY-1a-UGc\" secondAttribute=\"leading\" constant=\"20\" id=\"Rek-hz-pDw\"/>\n                                    <constraint firstItem=\"xOL-Sq-r4i\" firstAttribute=\"top\" secondItem=\"XgY-1a-UGc\" secondAttribute=\"top\" constant=\"23\" id=\"Udf-0g-bZm\"/>\n                                    <constraint firstItem=\"Tdu-YQ-saq\" firstAttribute=\"top\" secondItem=\"vz0-qg-GcZ\" secondAttribute=\"bottom\" constant=\"17\" id=\"WiR-yP-dyv\"/>\n                                    <constraint firstItem=\"Mde-Cm-CoS\" firstAttribute=\"centerY\" secondItem=\"7CF-rV-pK2\" secondAttribute=\"centerY\" id=\"eaN-FA-4mF\"/>\n                                    <constraint firstItem=\"iGp-rp-t1d\" firstAttribute=\"centerY\" secondItem=\"7CF-rV-pK2\" secondAttribute=\"centerY\" id=\"hBb-mp-AjF\"/>\n                                    <constraint firstItem=\"l4N-LL-ZrJ\" firstAttribute=\"top\" secondItem=\"Tdu-YQ-saq\" secondAttribute=\"bottom\" constant=\"24\" id=\"iA5-RB-pW2\"/>\n                                    <constraint firstItem=\"vz0-qg-GcZ\" firstAttribute=\"top\" secondItem=\"XgY-1a-UGc\" secondAttribute=\"top\" constant=\"21\" id=\"iad-6N-wNf\"/>\n                                    <constraint firstItem=\"vz0-qg-GcZ\" firstAttribute=\"leading\" secondItem=\"WHN-wR-TKt\" secondAttribute=\"trailing\" constant=\"6\" id=\"jgu-tV-gqO\"/>\n                                    <constraint firstItem=\"WHN-wR-TKt\" firstAttribute=\"centerY\" secondItem=\"vz0-qg-GcZ\" secondAttribute=\"centerY\" id=\"kTu-fb-Bc8\"/>\n                                    <constraint firstAttribute=\"trailing\" secondItem=\"vz0-qg-GcZ\" secondAttribute=\"trailing\" constant=\"18\" id=\"ktq-JT-uoR\"/>\n                                    <constraint firstItem=\"xOL-Sq-r4i\" firstAttribute=\"leading\" secondItem=\"XgY-1a-UGc\" secondAttribute=\"leading\" constant=\"20\" id=\"pY0-qd-xmK\"/>\n                                    <constraint firstItem=\"l4N-LL-ZrJ\" firstAttribute=\"trailing\" secondItem=\"Tdu-YQ-saq\" secondAttribute=\"trailing\" id=\"ql2-Z9-dnv\"/>\n                                    <constraint firstItem=\"iGp-rp-t1d\" firstAttribute=\"leading\" secondItem=\"7CF-rV-pK2\" secondAttribute=\"trailing\" constant=\"20\" id=\"vWD-0m-dMp\"/>\n                                    <constraint firstItem=\"7CF-rV-pK2\" firstAttribute=\"centerY\" secondItem=\"Tdu-YQ-saq\" secondAttribute=\"centerY\" id=\"x0d-LB-A4q\"/>\n                                    <constraint firstItem=\"7CF-rV-pK2\" firstAttribute=\"leading\" secondItem=\"xOL-Sq-r4i\" secondAttribute=\"leading\" id=\"yEL-Nv-z76\"/>\n                                </constraints>\n                            </view>\n                        </subviews>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\"/>\n                        <constraints>\n                            <constraint firstItem=\"F9K-jU-100\" firstAttribute=\"trailing\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"trailing\" id=\"1es-nY-bd3\"/>\n                            <constraint firstItem=\"F9K-jU-100\" firstAttribute=\"leading\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"leading\" id=\"A3E-iv-1qp\"/>\n                            <constraint firstItem=\"XgY-1a-UGc\" firstAttribute=\"trailing\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"trailing\" id=\"Luk-cg-4Ez\"/>\n                            <constraint firstItem=\"UCB-SP-lQk\" firstAttribute=\"leading\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"leading\" id=\"Qbw-Rq-Rhw\"/>\n                            <constraint firstItem=\"F9K-jU-100\" firstAttribute=\"top\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"top\" id=\"VLb-cX-ZHC\"/>\n                            <constraint firstItem=\"XgY-1a-UGc\" firstAttribute=\"leading\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"leading\" id=\"Y8A-sq-fmq\"/>\n                            <constraint firstItem=\"XgY-1a-UGc\" firstAttribute=\"top\" secondItem=\"UCB-SP-lQk\" secondAttribute=\"bottom\" id=\"eof-MM-DrW\"/>\n                            <constraint firstItem=\"UCB-SP-lQk\" firstAttribute=\"top\" secondItem=\"F9K-jU-100\" secondAttribute=\"bottom\" id=\"hwL-ec-fKo\"/>\n                            <constraint firstItem=\"UCB-SP-lQk\" firstAttribute=\"trailing\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"trailing\" id=\"o6z-Dj-ppC\"/>\n                            <constraint firstItem=\"XgY-1a-UGc\" firstAttribute=\"bottom\" secondItem=\"6Tk-OE-BBY\" secondAttribute=\"bottom\" id=\"vnZ-9k-MfI\"/>\n                        </constraints>\n                        <userDefinedRuntimeAttributes>\n                            <userDefinedRuntimeAttribute type=\"boolean\" keyPath=\"isSkeletonable\" value=\"YES\"/>\n                        </userDefinedRuntimeAttributes>\n                    </view>\n                    <tabBarItem key=\"tabBarItem\" title=\"Item\" id=\"wQY-ap-3n3\"/>\n                    <navigationItem key=\"navigationItem\" id=\"BEI-dU-kr2\"/>\n                    <connections>\n                        <outlet property=\"avatarImage\" destination=\"nMj-pU-5wJ\" id=\"9fa-Z7-vYi\"/>\n                        <outlet property=\"colorSelectedView\" destination=\"iGp-rp-t1d\" id=\"0Zm-9d-jRU\"/>\n                        <outlet property=\"showOrHideSkeletonButton\" destination=\"Tdu-YQ-saq\" id=\"gkm-mB-zYD\"/>\n                        <outlet property=\"skeletonTypeSelector\" destination=\"xOL-Sq-r4i\" id=\"yTr-8L-I4Y\"/>\n                        <outlet property=\"switchAnimated\" destination=\"vz0-qg-GcZ\" id=\"d2R-8x-lRb\"/>\n                        <outlet property=\"tableview\" destination=\"UCB-SP-lQk\" id=\"XV0-KX-lAN\"/>\n                        <outlet property=\"transitionDurationLabel\" destination=\"mrw-PM-jJJ\" id=\"BVK-Kl-5Q3\"/>\n                        <outlet property=\"transitionDurationStepper\" destination=\"l4N-LL-ZrJ\" id=\"OJr-Ul-7XR\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-2682.4000000000001\" y=\"339.90147783251234\"/>\n        </scene>\n        <!--Item-->\n        <scene sceneID=\"Cfc-AT-AS1\">\n            <objects>\n                <viewController id=\"dv8-ph-Ehg\" customClass=\"UITextViewByCodeViewController\" customModule=\"iOS_Example\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Jwx-gI-Qod\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"812\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"Ao1-hk-zrH\"/>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\"/>\n                    </view>\n                    <tabBarItem key=\"tabBarItem\" title=\"Item\" id=\"iKp-9S-aib\"/>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"M03-a6-GOC\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-1644\" y=\"340\"/>\n        </scene>\n        <!--Tab Bar Controller-->\n        <scene sceneID=\"U6k-MC-AHH\">\n            <objects>\n                <tabBarController automaticallyAdjustsScrollViewInsets=\"NO\" id=\"Va7-1y-Tel\" sceneMemberID=\"viewController\">\n                    <toolbarItems/>\n                    <tabBar key=\"tabBar\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"HSI-2O-RyO\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"1000\" height=\"1000\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                    </tabBar>\n                    <connections>\n                        <segue destination=\"BYZ-38-t0r\" kind=\"relationship\" relationship=\"viewControllers\" id=\"dL3-9L-KNU\"/>\n                        <segue destination=\"dv8-ph-Ehg\" kind=\"relationship\" relationship=\"viewControllers\" id=\"8QB-uV-gaF\"/>\n                    </connections>\n                </tabBarController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"huq-Fh-0sW\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-2172\" y=\"-555\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"avatar\" width=\"215\" height=\"211\"/>\n        <systemColor name=\"labelColor\">\n            <color white=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n        </systemColor>\n        <systemColor name=\"systemBackgroundColor\">\n            <color white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n        </systemColor>\n    </resources>\n</document>\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Cell.swift",
    "content": "//\n//  Cell.swift\n//  SkeletonViewExample\n//\n//  Created by Juanpe Catalán on 03/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nclass Cell: UITableViewCell {\n\n    @IBOutlet weak var avatar: UIImageView!\n    @IBOutlet weak var label1: UILabel!\n    @IBOutlet weak var textField: UITextField!\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        setUpInputAccessoryView()\n    }\n\n    func setUpInputAccessoryView() {\n        let bar = UIToolbar()\n        let reset = UIBarButtonItem(title: \"InputAccessoryView\", style: .plain, target: self, action: #selector(resetTapped))\n        bar.items = [reset]\n        bar.sizeToFit()\n        textField.inputAccessoryView = bar\n    }\n\n    @objc func resetTapped() {\n\n    }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Constants.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\nlet colors = [(UIColor.skeletonDefault,\"skeletonDefault\"),(UIColor.turquoise,\"turquoise\"), (UIColor.emerald,\"emerald\"), (UIColor.peterRiver,\"peterRiver\"), (UIColor.amethyst,\"amethyst\"),(UIColor.wetAsphalt,\"wetAsphalt\"), (UIColor.nephritis,\"nephritis\"), (UIColor.belizeHole,\"belizeHole\"), (UIColor.wisteria,\"wisteria\"), (UIColor.midnightBlue,\"midnightBlue\"), (UIColor.sunFlower,\"sunFlower\"), (UIColor.carrot,\"carrot\"), (UIColor.alizarin,\"alizarin\"),(UIColor.clouds,\"clouds\"), (UIColor.concrete,\"concrete\"), (UIColor.flatOrange,\"flatOrange\"), (UIColor.pumpkin,\"pumpkin\"), (UIColor.pomegranate,\"pomegranate\"), (UIColor.silver,\"silver\"), (UIColor.asbestos,\"asbestos\")]\n"
  },
  {
    "path": "Examples/iOS Example/Sources/HeaderFooterSection.swift",
    "content": "// Copyright © 2020 SkeletonView. All rights reserved.\n\nimport UIKit\n\nclass HeaderFooterSection: UITableViewHeaderFooterView {\n    \n    lazy var titleLabel: UILabel = {\n        let label =  UILabel()\n\n        label.text = \"      \"\n        label.isSkeletonable = true\n        label.linesCornerRadius = 10\n\n        return label\n    }()\n    \n    override init(reuseIdentifier: String?) {\n        super.init(reuseIdentifier: reuseIdentifier)\n        \n        isSkeletonable = true\n        \n        contentView.addSubview(titleLabel)\n\n        titleLabel.translatesAutoresizingMaskIntoConstraints = false\n        \n        NSLayoutConstraint.activate([\n            titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10),\n            titleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),\n            titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),\n            titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10)\n        ])\n        \n        backgroundView = UIView()\n        if #available(iOS 13.0, *) {\n            backgroundView?.backgroundColor = .systemBackground\n        } else {\n            backgroundView?.backgroundColor = .white\n        }\n    }\n    \n    required init?(coder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIApplicationSupportsIndirectInputEvents</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Examples/iOS Example/Sources/UITextViewByCodeViewController.swift",
    "content": "//  Copyright © 2022 SkeletonView. All rights reserved.\n\nimport UIKit\nimport SkeletonView\n\nclass UITextViewByCodeViewController: UIViewController {\n    lazy var textView: UITextView = {\n        let tv = UITextView()\n        \n        tv.text = \"              \"\n        tv.linesCornerRadius = 10\n        tv.isSkeletonable = true\n        tv.translatesAutoresizingMaskIntoConstraints = false\n        \n        return tv\n    }()\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        setupUI()\n        setupElementsConstraints()\n        showSkeletonForElements()\n    }\n    \n    override func viewWillAppear(_ animated: Bool) {\n        super.viewWillAppear(animated)\n    }\n    \n    func setupUI() {\n        view.addSubview(textView)\n    }\n    \n    func setupElementsConstraints() {\n        textView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true\n        textView.leftAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leftAnchor, constant: 10).isActive = true\n        textView.rightAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true\n        textView.heightAnchor.constraint(equalToConstant: 100).isActive = true\n    }\n    \n    func showSkeletonForElements() {\n        textView.showSkeleton()\n    }\n}\n"
  },
  {
    "path": "Examples/iOS Example/Sources/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  SkeletonViewExample\n//\n//  Created by Juanpe Catalán on 02/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\nimport SkeletonView\n\nclass ViewController: UIViewController {\n    @IBOutlet weak var tableview: UITableView! {\n        didSet {\n            tableview.rowHeight = UITableView.automaticDimension\n            tableview.sectionHeaderHeight = UITableView.automaticDimension\n            tableview.sectionFooterHeight = UITableView.automaticDimension\n            tableview.estimatedRowHeight = 120.0\n            tableview.estimatedSectionFooterHeight = 20.0\n            tableview.estimatedSectionHeaderHeight = 20.0\n            tableview.register(HeaderFooterSection.self, forHeaderFooterViewReuseIdentifier: \"HeaderIdentifier\")\n            tableview.register(HeaderFooterSection.self, forHeaderFooterViewReuseIdentifier: \"FooterIdentifier\")\n        }\n    }\n    \n    @IBOutlet weak var avatarImage: UIImageView! {\n        didSet {\n            avatarImage.layer.cornerRadius = avatarImage.frame.width/2\n            avatarImage.layer.masksToBounds = true\n        } \n    }\n    \n    @IBOutlet weak var colorSelectedView: UIView! {\n        didSet {\n            colorSelectedView.layer.cornerRadius = 5\n            colorSelectedView.layer.masksToBounds = true\n            colorSelectedView.backgroundColor = SkeletonAppearance.default.tintColor\n        }\n    }\n\n    @IBOutlet weak var switchAnimated: UISwitch!\n    @IBOutlet weak var skeletonTypeSelector: UISegmentedControl!\n    @IBOutlet weak var showOrHideSkeletonButton: UIButton!\n    @IBOutlet weak var transitionDurationLabel: UILabel!\n    @IBOutlet weak var transitionDurationStepper: UIStepper!\n    \n    var type: SkeletonType {\n        return skeletonTypeSelector.selectedSegmentIndex == 0 ? .solid : .gradient\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        tableview.isSkeletonable = true\n        transitionDurationStepper.value = 0.25\n    }\n    \n    override func viewDidAppear(_ animated: Bool) {\n        super.viewDidAppear(animated)\n        view.showAnimatedSkeleton()\n    }\n\n    @IBAction func changeAnimated(_ sender: Any) {\n        if switchAnimated.isOn {\n            view.startSkeletonAnimation()\n        } else {\n            view.stopSkeletonAnimation()\n        }\n    }\n    \n    @IBAction func changeSkeletonType(_ sender: Any) {\n        refreshSkeleton()\n    }\n    \n    @IBAction func btnChangeColorTouchUpInside(_ sender: Any) {\n        showAlertPicker()\n    }\n    \n    @IBAction func showOrHideSkeleton(_ sender: Any) {\n        showOrHideSkeletonButton.setTitle((view.sk.isSkeletonActive ? \"Show skeleton\" : \"Hide skeleton\"), for: .normal)\n        view.sk.isSkeletonActive ? hideSkeleton() : showSkeleton()\n    }\n    \n    @IBAction func transitionDurationStepperAction(_ sender: Any) {\n        transitionDurationLabel.text = \"Transition duration: \\(transitionDurationStepper.value) sec\"\n    }\n    \n    func showSkeleton() {\n        if type == .gradient {\n            let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)\n            if switchAnimated.isOn {\n                view.showAnimatedGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))\n            }\n            else {\n                view.showGradientSkeleton(usingGradient: gradient, transition: .crossDissolve(transitionDurationStepper.value))\n            }\n        }\n        else {\n            if switchAnimated.isOn {\n                view.showAnimatedSkeleton(transition: .crossDissolve(transitionDurationStepper.value))\n            }\n            else {\n                view.showSkeleton(transition: .crossDissolve(transitionDurationStepper.value))\n            }\n        }\n    }\n    \n    func hideSkeleton() {\n        view.hideSkeleton(transition: .crossDissolve(transitionDurationStepper.value))\n    }\n    \n    func refreshSkeleton() {\n        if type == .gradient { showOrUpdateGradientSkeleton() }\n        else { showOrUpdatepdateSolidSkeleton() }\n    }\n    \n    func showOrUpdatepdateSolidSkeleton() {\n        if switchAnimated.isOn {\n            view.updateAnimatedSkeleton(usingColor: colorSelectedView.backgroundColor!)\n        } else {\n            view.updateSkeleton(usingColor: colorSelectedView.backgroundColor!)\n        }\n    }\n    \n    func showOrUpdateGradientSkeleton() {\n        let gradient = SkeletonGradient(baseColor: colorSelectedView.backgroundColor!)\n        if switchAnimated.isOn {\n            view.updateAnimatedGradientSkeleton(usingGradient: gradient)\n        } else {\n            view.updateGradientSkeleton(usingGradient: gradient)\n        }\n    }\n    \n    func showAlertPicker() {\n        let alertView = UIAlertController(title: \"Select color\", message: \"\\n\\n\\n\\n\\n\\n\", preferredStyle: .alert)\n        \n        let pickerView = UIPickerView(frame: CGRect(x: 0, y: 50, width: 260, height: 115))\n        pickerView.dataSource = self\n        pickerView.delegate = self\n        \n        alertView.view.addSubview(pickerView)\n        \n        let action = UIAlertAction(title: \"OK\", style: .default) { [unowned pickerView, unowned self] _ in\n            let row = pickerView.selectedRow(inComponent: 0)\n            self.colorSelectedView.backgroundColor = colors[row].0\n            self.refreshSkeleton()\n        }\n        alertView.addAction(action)\n        \n        let cancelAction = UIAlertAction(title: \"Cancel\", style: .cancel, handler: nil)\n        alertView.addAction(cancelAction)\n        \n        present(alertView, animated: false, completion: {\n            pickerView.frame.size.width = alertView.view.frame.size.width\n        })\n    }\n}\n\nextension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {\n    func numberOfComponents(in pickerView: UIPickerView) -> Int {\n        return 1\n    }\n    \n    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {\n       return colors.count\n    }\n    \n    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {\n        return colors[row].1\n    }\n}\n\nextension ViewController: SkeletonTableViewDataSource {\n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return 10\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n        return \"CellIdentifier\"\n    }\n    \n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        let cell = tableView.dequeueReusableCell(withIdentifier: \"CellIdentifier\", for: indexPath) as! Cell\n        cell.label1.text = \"cell -> \\(indexPath.row)\"\n        return cell\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {\n        let cell = skeletonView.dequeueReusableCell(withIdentifier: \"CellIdentifier\", for: indexPath) as? Cell\n        cell?.textField.isHidden = indexPath.row == 0\n        return cell\n    }\n\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {\n        let cell = cell as? Cell\n        cell?.textField.isHidden = indexPath.row == 0\n    }\n}\n\nextension ViewController: SkeletonTableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? {\n        return \"HeaderIdentifier\"\n    }\n\n    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {\n        let header = tableView\n            .dequeueReusableHeaderFooterView(withIdentifier: \"HeaderIdentifier\") as! HeaderFooterSection\n        header.titleLabel.text = \"header -> \\(section)\"\n        return header\n    }\n\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? {\n        return \"FooterIdentifier\"\n    }\n\n    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {\n        let footer = tableView\n            .dequeueReusableHeaderFooterView(withIdentifier: \"FooterIdentifier\") as! HeaderFooterSection\n        footer.titleLabel.text = \"footer -> \\(section)\"\n        return footer\n    }\n}\n"
  },
  {
    "path": "Examples/iOS Example/iOS Example.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tE21D8BB727888D050041DBCE /* UITextViewByCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */; };\n\t\tF556F5C026CD20A300A80B83 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F5B726CD20A300A80B83 /* ViewController.swift */; };\n\t\tF556F5C126CD20A300A80B83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F556F5B826CD20A300A80B83 /* Assets.xcassets */; };\n\t\tF556F5C226CD20A300A80B83 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */; };\n\t\tF556F5C326CD20A300A80B83 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F5BB26CD20A300A80B83 /* Main.storyboard */; };\n\t\tF556F5C426CD20A300A80B83 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F5BD26CD20A300A80B83 /* AppDelegate.swift */; };\n\t\tF556F5E626CD21D300A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F5E026CD21CB00A80B83 /* SkeletonView.framework */; };\n\t\tF556F6EE26CE813F00A80B83 /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6E626CE813F00A80B83 /* Cell.swift */; };\n\t\tF556F6EF26CE813F00A80B83 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6EC26CE813F00A80B83 /* Constants.swift */; };\n\t\tF556F6F026CE813F00A80B83 /* HeaderFooterSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tF556F5DF26CD21CB00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonView::Product\";\n\t\t\tremoteInfo = \"SkeletonView iOS\";\n\t\t};\n\t\tF556F5E126CD21CB00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonViewTests::Product\";\n\t\t\tremoteInfo = SkeletonViewTests;\n\t\t};\n\t\tF556F5E326CD21CB00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = F556F59426CD1F3900A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS\";\n\t\t};\n\t\tF556F5E926CD21DA00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonView\";\n\t\t\tremoteInfo = \"SkeletonView iOS\";\n\t\t};\n\t\tF556F6EA26CE813F00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = F556F67126CD458500A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS Tests\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tE21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewByCodeViewController.swift; sourceTree = \"<group>\"; };\n\t\tF556F59F26CD201B00A80B83 /* iOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"iOS Example.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF556F5B726CD20A300A80B83 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\tF556F5B826CD20A300A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tF556F5BA26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tF556F5BC26CD20A300A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tF556F5BD26CD20A300A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tF556F5BE26CD20A300A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tF556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = \"<group>\"; };\n\t\tF556F6E626CE813F00A80B83 /* Cell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = \"<group>\"; };\n\t\tF556F6EC26CE813F00A80B83 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = \"<group>\"; };\n\t\tF556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderFooterSection.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tF556F59C26CD201B00A80B83 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F5E626CD21D300A80B83 /* SkeletonView.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tF556F59626CD201B00A80B83 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F5B626CD20A300A80B83 /* Sources */,\n\t\t\t\tF556F5A026CD201B00A80B83 /* Products */,\n\t\t\t\tF556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F5A026CD201B00A80B83 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F59F26CD201B00A80B83 /* iOS Example.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F5B626CD20A300A80B83 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F6E626CE813F00A80B83 /* Cell.swift */,\n\t\t\t\tF556F6EC26CE813F00A80B83 /* Constants.swift */,\n\t\t\t\tF556F6ED26CE813F00A80B83 /* HeaderFooterSection.swift */,\n\t\t\t\tF556F5B726CD20A300A80B83 /* ViewController.swift */,\n\t\t\t\tE21D8BB627888D050041DBCE /* UITextViewByCodeViewController.swift */,\n\t\t\t\tF556F5B826CD20A300A80B83 /* Assets.xcassets */,\n\t\t\t\tF556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */,\n\t\t\t\tF556F5BB26CD20A300A80B83 /* Main.storyboard */,\n\t\t\t\tF556F5BD26CD20A300A80B83 /* AppDelegate.swift */,\n\t\t\t\tF556F5BE26CD20A300A80B83 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = Sources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F5DA26CD21CB00A80B83 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F5E026CD21CB00A80B83 /* SkeletonView.framework */,\n\t\t\t\tF556F5E226CD21CB00A80B83 /* SkeletonViewTests.xctest */,\n\t\t\t\tF556F5E426CD21CB00A80B83 /* SkeletonView.framework */,\n\t\t\t\tF556F6EB26CE813F00A80B83 /* SkeletonView tvOS Tests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tF556F59E26CD201B00A80B83 /* iOS Example */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F556F5B326CD201C00A80B83 /* Build configuration list for PBXNativeTarget \"iOS Example\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF556F59B26CD201B00A80B83 /* Sources */,\n\t\t\t\tF556F59C26CD201B00A80B83 /* Frameworks */,\n\t\t\t\tF556F59D26CD201B00A80B83 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tF556F5EA26CD21DA00A80B83 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"iOS Example\";\n\t\t\tproductName = \"iOS Example\";\n\t\t\tproductReference = F556F59F26CD201B00A80B83 /* iOS Example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tF556F59726CD201B00A80B83 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1250;\n\t\t\t\tLastUpgradeCheck = 1300;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tF556F59E26CD201B00A80B83 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.5.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = F556F59A26CD201B00A80B83 /* Build configuration list for PBXProject \"iOS Example\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = F556F59626CD201B00A80B83;\n\t\t\tproductRefGroup = F556F5A026CD201B00A80B83 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = F556F5DA26CD21CB00A80B83 /* Products */;\n\t\t\t\t\tProjectRef = F556F5D926CD21CB00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tF556F59E26CD201B00A80B83 /* iOS Example */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\tF556F5E026CD21CB00A80B83 /* SkeletonView.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = SkeletonView.framework;\n\t\t\tremoteRef = F556F5DF26CD21CB00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F5E226CD21CB00A80B83 /* SkeletonViewTests.xctest */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.cfbundle;\n\t\t\tpath = SkeletonViewTests.xctest;\n\t\t\tremoteRef = F556F5E126CD21CB00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F5E426CD21CB00A80B83 /* SkeletonView.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = SkeletonView.framework;\n\t\t\tremoteRef = F556F5E326CD21CB00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F6EB26CE813F00A80B83 /* SkeletonView tvOS Tests.xctest */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.cfbundle;\n\t\t\tpath = \"SkeletonView tvOS Tests.xctest\";\n\t\t\tremoteRef = F556F6EA26CE813F00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tF556F59D26CD201B00A80B83 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F5C326CD20A300A80B83 /* Main.storyboard in Resources */,\n\t\t\t\tF556F5C126CD20A300A80B83 /* Assets.xcassets in Resources */,\n\t\t\t\tF556F5C226CD20A300A80B83 /* LaunchScreen.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tF556F59B26CD201B00A80B83 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F6EF26CE813F00A80B83 /* Constants.swift in Sources */,\n\t\t\t\tF556F5C426CD20A300A80B83 /* AppDelegate.swift in Sources */,\n\t\t\t\tF556F6EE26CE813F00A80B83 /* Cell.swift in Sources */,\n\t\t\t\tF556F5C026CD20A300A80B83 /* ViewController.swift in Sources */,\n\t\t\t\tF556F6F026CE813F00A80B83 /* HeaderFooterSection.swift in Sources */,\n\t\t\t\tE21D8BB727888D050041DBCE /* UITextViewByCodeViewController.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tF556F5EA26CD21DA00A80B83 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = \"SkeletonView iOS\";\n\t\t\ttargetProxy = F556F5E926CD21DA00A80B83 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tF556F5B926CD20A300A80B83 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F5BA26CD20A300A80B83 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F5BB26CD20A300A80B83 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F5BC26CD20A300A80B83 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tF556F5B126CD201C00A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.5;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F5B226CD201C00A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.5;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF556F5B426CD201C00A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Sources/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.iOS-Example\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F5B526CD201C00A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Sources/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.iOS-Example\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tF556F59A26CD201B00A80B83 /* Build configuration list for PBXProject \"iOS Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F5B126CD201C00A80B83 /* Debug */,\n\t\t\t\tF556F5B226CD201C00A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF556F5B326CD201C00A80B83 /* Build configuration list for PBXNativeTarget \"iOS Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F5B426CD201C00A80B83 /* Debug */,\n\t\t\t\tF556F5B526CD201C00A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = F556F59726CD201B00A80B83 /* Project object */;\n}\n"
  },
  {
    "path": "Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Examples/iOS Example/iOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  tvOS Example\n//\n//  Created by Juanpe Catalán on 18/8/21.\n//\n\nimport UIKit\n\n@main\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n        // Override point for customization after application launch.\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"layers\" : [\n    {\n      \"filename\" : \"Front.imagestacklayer\"\n    },\n    {\n      \"filename\" : \"Middle.imagestacklayer\"\n    },\n    {\n      \"filename\" : \"Back.imagestacklayer\"\n    }\n  ]\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  },\n  \"layers\" : [\n    {\n      \"filename\" : \"Front.imagestacklayer\"\n    },\n    {\n      \"filename\" : \"Middle.imagestacklayer\"\n    },\n    {\n      \"filename\" : \"Back.imagestacklayer\"\n    }\n  ]\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json",
    "content": "{\n  \"assets\" : [\n    {\n      \"filename\" : \"App Icon - App Store.imagestack\",\n      \"idiom\" : \"tv\",\n      \"role\" : \"primary-app-icon\",\n      \"size\" : \"1280x768\"\n    },\n    {\n      \"filename\" : \"App Icon.imagestack\",\n      \"idiom\" : \"tv\",\n      \"role\" : \"primary-app-icon\",\n      \"size\" : \"400x240\"\n    },\n    {\n      \"filename\" : \"Top Shelf Image Wide.imageset\",\n      \"idiom\" : \"tv\",\n      \"role\" : \"top-shelf-image-wide\",\n      \"size\" : \"2320x720\"\n    },\n    {\n      \"filename\" : \"Top Shelf Image.imageset\",\n      \"idiom\" : \"tv\",\n      \"role\" : \"top-shelf-image\",\n      \"size\" : \"1920x720\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"tv-marketing\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv-marketing\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"tv-marketing\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"tv-marketing\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder.AppleTV.Storyboard\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"AppleTV\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"1920\" height=\"1080\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"wu6-TO-1qx\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder.AppleTV.Storyboard\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"AppleTV\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"y3c-jy-aDJ\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"wfy-db-euE\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"1920\" height=\"1080\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"wu6-TO-1qx\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>arm64</string>\n\t</array>\n\t<key>UIUserInterfaceStyle</key>\n\t<string>Automatic</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Examples/tvOS Example/Sources/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  tvOS Example\n//\n//  Created by Juanpe Catalán on 18/8/21.\n//\n\nimport UIKit\n\nclass ViewController: UIViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        // Do any additional setup after loading the view.\n    }\n\n\n}\n\n"
  },
  {
    "path": "Examples/tvOS Example/tvOS Example.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tF556F61226CD224900A80B83 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F60A26CD224900A80B83 /* ViewController.swift */; };\n\t\tF556F61326CD224900A80B83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F556F60B26CD224900A80B83 /* Assets.xcassets */; };\n\t\tF556F61426CD224900A80B83 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F60C26CD224900A80B83 /* LaunchScreen.storyboard */; };\n\t\tF556F61526CD224900A80B83 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F556F60E26CD224900A80B83 /* Main.storyboard */; };\n\t\tF556F61626CD224900A80B83 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F61026CD224900A80B83 /* AppDelegate.swift */; };\n\t\tF556F62526CD225C00A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F62326CD224F00A80B83 /* SkeletonView.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tF556F61E26CD224F00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonView::Product\";\n\t\t\tremoteInfo = \"SkeletonView iOS\";\n\t\t};\n\t\tF556F62026CD224F00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonViewTests::Product\";\n\t\t\tremoteInfo = SkeletonViewTests;\n\t\t};\n\t\tF556F62226CD224F00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = F556F59426CD1F3900A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS\";\n\t\t};\n\t\tF556F62826CD226600A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = F556F56426CD1F3900A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS\";\n\t\t};\n\t\tF556F6FE26CE88DC00A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = F556F67126CD458500A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS Tests\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tF556F5F426CD221300A80B83 /* tvOS Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"tvOS Example.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF556F60A26CD224900A80B83 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\tF556F60B26CD224900A80B83 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tF556F60D26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tF556F60F26CD224900A80B83 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tF556F61026CD224900A80B83 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tF556F61126CD224900A80B83 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tF556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = SkeletonView.xcodeproj; path = ../../SkeletonView.xcodeproj; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tF556F5F126CD221300A80B83 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F62526CD225C00A80B83 /* SkeletonView.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tF556F5EB26CD221300A80B83 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F60926CD224900A80B83 /* Sources */,\n\t\t\t\tF556F5F526CD221300A80B83 /* Products */,\n\t\t\t\tF556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F5F526CD221300A80B83 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F5F426CD221300A80B83 /* tvOS Example.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F60926CD224900A80B83 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F60A26CD224900A80B83 /* ViewController.swift */,\n\t\t\t\tF556F60B26CD224900A80B83 /* Assets.xcassets */,\n\t\t\t\tF556F60C26CD224900A80B83 /* LaunchScreen.storyboard */,\n\t\t\t\tF556F60E26CD224900A80B83 /* Main.storyboard */,\n\t\t\t\tF556F61026CD224900A80B83 /* AppDelegate.swift */,\n\t\t\t\tF556F61126CD224900A80B83 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = Sources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F61926CD224F00A80B83 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F61F26CD224F00A80B83 /* SkeletonView.framework */,\n\t\t\t\tF556F62126CD224F00A80B83 /* SkeletonViewTests.xctest */,\n\t\t\t\tF556F62326CD224F00A80B83 /* SkeletonView.framework */,\n\t\t\t\tF556F6FF26CE88DC00A80B83 /* SkeletonView tvOS Tests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tF556F5F326CD221300A80B83 /* tvOS Example */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F556F60626CD221400A80B83 /* Build configuration list for PBXNativeTarget \"tvOS Example\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF556F5F026CD221300A80B83 /* Sources */,\n\t\t\t\tF556F5F126CD221300A80B83 /* Frameworks */,\n\t\t\t\tF556F5F226CD221300A80B83 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tF556F62926CD226600A80B83 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"tvOS Example\";\n\t\t\tproductName = \"tvOS Example\";\n\t\t\tproductReference = F556F5F426CD221300A80B83 /* tvOS Example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tF556F5EC26CD221300A80B83 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1250;\n\t\t\t\tLastUpgradeCheck = 1300;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tF556F5F326CD221300A80B83 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.5.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = F556F5EF26CD221300A80B83 /* Build configuration list for PBXProject \"tvOS Example\" */;\n\t\t\tcompatibilityVersion = \"Xcode 9.3\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = F556F5EB26CD221300A80B83;\n\t\t\tproductRefGroup = F556F5F526CD221300A80B83 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = F556F61926CD224F00A80B83 /* Products */;\n\t\t\t\t\tProjectRef = F556F61826CD224F00A80B83 /* SkeletonView.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tF556F5F326CD221300A80B83 /* tvOS Example */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\tF556F61F26CD224F00A80B83 /* SkeletonView.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = SkeletonView.framework;\n\t\t\tremoteRef = F556F61E26CD224F00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F62126CD224F00A80B83 /* SkeletonViewTests.xctest */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.cfbundle;\n\t\t\tpath = SkeletonViewTests.xctest;\n\t\t\tremoteRef = F556F62026CD224F00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F62326CD224F00A80B83 /* SkeletonView.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = SkeletonView.framework;\n\t\t\tremoteRef = F556F62226CD224F00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tF556F6FF26CE88DC00A80B83 /* SkeletonView tvOS Tests.xctest */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.cfbundle;\n\t\t\tpath = \"SkeletonView tvOS Tests.xctest\";\n\t\t\tremoteRef = F556F6FE26CE88DC00A80B83 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tF556F5F226CD221300A80B83 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F61526CD224900A80B83 /* Main.storyboard in Resources */,\n\t\t\t\tF556F61326CD224900A80B83 /* Assets.xcassets in Resources */,\n\t\t\t\tF556F61426CD224900A80B83 /* LaunchScreen.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tF556F5F026CD221300A80B83 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F61626CD224900A80B83 /* AppDelegate.swift in Sources */,\n\t\t\t\tF556F61226CD224900A80B83 /* ViewController.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tF556F62926CD226600A80B83 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = \"SkeletonView tvOS\";\n\t\t\ttargetProxy = F556F62826CD226600A80B83 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tF556F60C26CD224900A80B83 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F60D26CD224900A80B83 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F60E26CD224900A80B83 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F60F26CD224900A80B83 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tF556F60426CD221400A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F60526CD221400A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF556F60726CD221400A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = Sources/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.tvOS-Example\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F60826CD221400A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = \"App Icon & Top Shelf Image\";\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tINFOPLIST_FILE = Sources/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.tvOS-Example\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tF556F5EF26CD221300A80B83 /* Build configuration list for PBXProject \"tvOS Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F60426CD221400A80B83 /* Debug */,\n\t\t\t\tF556F60526CD221400A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF556F60626CD221400A80B83 /* Build configuration list for PBXNativeTarget \"tvOS Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F60726CD221400A80B83 /* Debug */,\n\t\t\t\tF556F60826CD221400A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = F556F5EC26CD221300A80B83 /* Project object */;\n}\n"
  },
  {
    "path": "Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Examples/tvOS Example/tvOS Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Gemfile",
    "content": "source \"https://rubygems.org\"\n\ngem \"fastlane\"\ngem 'cocoapods', '~> 1.7.0.beta.2'\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "Package.swift",
    "content": "// swift-tools-version:5.3\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"SkeletonView\",\n    platforms: [\n        .iOS(.v9),\n        .tvOS(.v9)\n    ],\n    products: [\n        .library(\n            name: \"SkeletonView\",\n            targets: [\"SkeletonView\"]\n        )\n    ],\n    targets: [\n        .target(\n            name: \"SkeletonView\",\n            path: \"SkeletonViewCore/Sources\",\n            resources: [.copy(\"Supporting Files/PrivacyInfo.xcprivacy\")]\n        ),\n        .testTarget(\n            name: \"SkeletonViewTests\",\n            dependencies: [\"SkeletonView\"],\n            path: \"SkeletonViewCore/Tests\"\n        )\n    ],\n    swiftLanguageVersions: [.v5]\n)\n"
  },
  {
    "path": "README.md",
    "content": "![](Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-main\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/1f37bbab-a1c8-4a4a-94d7-f21740d461e9\" /></a>\n    <a href=\"https://cocoapods.org/pods/SkeletonView\"><img src=\"https://img.shields.io/cocoapods/v/SkeletonView.svg?style=flat\"></a>\n    <a href=\"https://github.com/Carthage/Carthage/\"><img src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\"></a>\n    <a href=\"https://swift.org/package-manager/\"><img src=\"https://img.shields.io/badge/SPM-supported-Green.svg?style=flat\"></a>\n    <img src=\"https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FJuanpe%2FSkeletonView%2Fbadge%3Ftype%3Dplatforms\"/>\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.20.0\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n</p>\n\n<p align=\"center\">\n    <a href=\"#-features\">Features</a>\n  • <a href=\"#-guides\">Guides</a>\n  • <a href=\"#-installation\">Installation</a>\n  • <a href=\"#-usage\">Usage</a>\n  • <a href=\"#-miscellaneous\">Miscellaneous</a>\n  • <a href=\"#️-contributing\">Contributing</a>\n</p>\n\n**🌎 README is available in other languages:  [🇪🇸](Translations/README_es.md) . [🇨🇳](Translations/README_zh.md) . [🇧🇷](Translations/README_pt-br.md) . [🇰🇷](Translations/README_ko.md) . [🇫🇷](Translations/README_fr.md) . [🇩🇪](Translations/README_de.md)**\n\nToday almost all apps have async processes, such as API requests, long running processes, etc. While the processes are working, usually developers place a loading view to show users that something is going on.\n\n**SkeletonView** has been conceived to address this need, an elegant way to show users that something is happening and also prepare them for which contents are waiting.\n\nEnjoy it! 🙂\n\n\n##\n- [🌟 Features](#-features)\n- [🎬 Guides](#-guides)\n- [📲 Installation](#-installation)\n- [🐒 Usage](#-usage)\n  - [🌿 Collections](#-collections)\n  - [🔠 Texts](#-texts)\n  - [🦋 Appearance](#-appearance)\n  - [🎨 Custom colors](#-custom-colors)\n  - [🏃‍♀️ Animations](#️-animations)\n  - [🏄 Transitions](#-transitions)\n- [✨ Miscellaneous](#-miscellaneous)\n- [❤️ Contributing](#️-contributing)\n- [📢 Mentions](#-mentions)\n- [🏆 Sponsors](#-sponsors)\n- [👨🏻‍💻 Author](#-author)\n- [👮🏻 License](#-license)\n\n\n\n## 🌟 Features\n\n* Easy to use\n* All UIViews are skeletonables\n* Fully customizable\n* Universal (iPhone & iPad)\n* Interface Builder friendly\n* Simple Swift syntax\n* Lightweight readable codebase\n\n\n## 🎬 Guides\n\n| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/Zx1Pg1gPfxA/maxresdefault.jpg)](https://www.youtube.com/watch?v=Zx1Pg1gPfxA)\n|:---:  | :---:  | :---: | :---:\n|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA)    by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8)    by iOS Academy| [**Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS**](https://www.youtube.com/watch?v=Zx1Pg1gPfxA) by MoureDev\n\n\n## 📲 Installation\n\n* [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html):\n\n```ruby\npod 'SkeletonView'\n```\n\n* [Carthage](https://github.com/Carthage/Carthage):\n\n```ruby\ngithub \"Juanpe/SkeletonView\"\n```\n\n* [Swift Package Manager](https://swift.org/package-manager/):\n\n```swift\ndependencies: [\n  .package(url: \"https://github.com/Juanpe/SkeletonView.git\", from: \"1.7.0\")\n]\n```\n\n> 📣 **IMPORTANT!** \n>\n> Since version 1.30.0, `SkeletonView` supports **XCFrameworks**, so if you want to install it as a **XCFramework**, please use [this repo](https://github.com/Juanpe/SkeletonView-XCFramework.git) instead.\n\n\n## 🐒 Usage\n\nOnly **3** steps needed to use `SkeletonView`:\n\n1️⃣ Import SkeletonView in proper place.\n```swift\nimport SkeletonView\n```\n\n2️⃣ Now, set which views will be `skeletonables`. You achieve this in two ways:\n\n**Using code:**\n```swift\navatarImageView.isSkeletonable = true\n```\n**Using IB/Storyboards:**\n\n![](Assets/storyboard.png)\n\n3️⃣ Once you've set the views, you can show the **skeleton**. To do so, you have **4** choices:\n\n```swift\n(1) view.showSkeleton()                 // Solid\n(2) view.showGradientSkeleton()         // Gradient\n(3) view.showAnimatedSkeleton()         // Solid animated\n(4) view.showAnimatedGradientSkeleton() // Gradient animated\n```\n\n**Preview**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Solid</center>\n</td>\n<td width=\"25%\">\n<center>Gradient</center>\n</td>\n<td width=\"25%\">\n<center>Solid Animated</center>\n</td>\n<td width=\"25%\">\n<center>Gradient Animated</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n\n> 📣 **IMPORTANT!** \n>\n> `SkeletonView` is recursive, so if you want show the skeleton in all skeletonable views, you only need to call the show method in the main container view. For example, with `UIViewControllers`.\n\n  \n\n\n### 🌿 Collections\n\n```SkeletonView``` is compatible with ```UITableView``` and ```UICollectionView```.\n\n\n**UITableView**\n\nIf you want to show the skeleton in a ```UITableView```, you need to conform to ```SkeletonTableViewDataSource``` protocol.\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int // Default: 1\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? // Default: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)\n}\n```\nAs you can see, this protocol inherits from ```UITableViewDataSource```, so you can replace this protocol with the skeleton protocol.\n\nThis protocol has a default implementation for some methods. For example, the number of rows for each section is calculated in runtime:\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// Default:\n// It calculates how many cells need to populate whole tableview\n```\n\n> 📣 **IMPORTANT!** \n>\n> If you return `UITableView.automaticNumberOfSkeletonRows` in the above method, it acts like the default behavior (i.e. it calculates how many cells needed to populate the whole tableview).\n\nThere is only one method you need to implement to let Skeleton know the cell identifier. This method doesn't have default implementation:\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n \n By default, the library dequeues the cells from each indexPath, but you can also do this if you want to make some changes before the skeleton appears:\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {\n     let cell = skeletonView.dequeueReusableCell(withIdentifier: \"CellIdentifier\", for: indexPath) as? Cell\n     cell?.textField.isHidden = indexPath.row == 0\n     return cell\n }\n ```\n \nIf you prefer to leave the deque part to the library you can configure the cell using this method:\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {\n     let cell = cell as? Cell\n     cell?.textField.isHidden = indexPath.row == 0\n }\n ```\n\n \nBesides, you can skeletonize both the headers and footers. You need to conform to `SkeletonTableViewDelegate` protocol.\n\n```swift\npublic protocol SkeletonTableViewDelegate: UITableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil\n}\n```\n\n> 📣 **IMPORTANT!** \n> \n> 1️⃣ If you are using resizable cells (**`tableView.rowHeight = UITableViewAutomaticDimension`**), it's mandatory define the **`estimatedRowHeight`**.\n> \n> 2️⃣ When you add elements in a **`UITableViewCell`** you should add it to **`contentView`** and not to the cell directly.\n> ```swift\n> self.contentView.addSubview(titleLabel) ✅         \n> self.addSubview(titleLabel) ❌\n> ```\n\n  \n\n**UICollectionView**\n\nFor `UICollectionView`, you need to conform to `SkeletonCollectionViewDataSource` protocol.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int  // default: 1\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // default: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell?  // default: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)\n}\n```\n\nThe rest of the process is the same as ```UITableView```\n\n\n### 🔠 Texts\n\n![](Assets/multilines2.png)\n\nWhen using elements with text, ```SkeletonView``` draws lines to simulate text.\n\nYou can set some properties for multilines elements.\n\n| Property | Type | Default | Preview\n| ------- | ------- |------- | -------\n| **lastLineFillPercent**  | `CGFloat` | `70`| ![](Assets/multiline_lastline.png)\n| **linesCornerRadius**  | `Int` | `0` | ![](Assets/multiline_corner.png)\n| **skeletonLineSpacing**  | `CGFloat` | `10` | ![](Assets/multiline_lineSpacing.png)\n| **skeletonPaddingInsets**  | `UIEdgeInsets` | `.zero` | ![](Assets/multiline_insets.png)\n| **skeletonTextLineHeight**  | `SkeletonTextLineHeight` | `.fixed(15)` | ![](Assets/multiline_lineHeight.png)\n| **skeletonTextNumberOfLines**  | `SkeletonTextNumberOfLines` | `.inherited` | ![](Assets/multiline_corner.png)\n\n<br />\n\nTo modify the percent or radius **using code**, set the properties:\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\nOr, if you prefer use **IB/Storyboard**:\n\n![](Assets/multiline_customize.png)\n\n<br />\n\n**How to define the number of lines?**\n\n\nBy default, the number of lines is the same as the value of the `numberOfLines` property. And, if it's set to **zero**, it'll calculate how many lines are needed to populate the whole skeleton and draw it.\n\nHowever, if you want to set a specific number of skeleton lines you can do it by setting the `skeletonTextNumberOfLines` property. This property has two possible values, `inherited` which returns `numberOfLines` value and `custom(Int)` which returns the specific number of lines specified as the associated value. \n\nFor example:\n\n```swift\nlabel.skeletonTextNumberOfLines = 3   // .custom(3)\n``` \n\n<br />\n\n> **⚠️ DEPRECATED!**\n>\n> **useFontLineHeight** has been deprecated. You can use **skeletonTextLineHeight** instead:\n> ```swift\n> descriptionTextView.skeletonTextLineHeight = .relativeToFont\n> ```\n\n> **📣 IMPORTANT!**\n>\n> Please note that for views without multiple lines, the single line will be considered \n> as the last line.\n\n\n\n### 🦋 Appearance\n\nThe skeletons have a default appearance. So, when you don't specify the color, gradient or multilines properties, `SkeletonView` uses the default values.\n\nDefault values:\n- **tintColor**: `UIColor`\n    - *default: `.skeletonDefault` (same as `.clouds` but adaptive to dark mode)*\n- **gradient**: SkeletonGradient\n  - *default: `SkeletonGradient(baseColor: .skeletonDefault)`*\n- **multilineHeight**: `CGFloat`\n  - *default: 15*\n- **multilineSpacing**: `CGFloat`\n  - *default: 10*\n- **multilineLastLineFillPercent**: `Int`\n  - *default: 70*\n- **multilineCornerRadius**: `Int`\n  - *default: 0*\n- **skeletonCornerRadius**: `CGFloat` (IBInspectable)  (Make your skeleton view with corner)\n  - *default: 0*\n\nTo get these default values you can use `SkeletonAppearance.default`. Using this property you can set the values as well:\n```swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n> **⚠️ DEPRECATED!**\n>\n> **useFontLineHeight** has been deprecated. You can use **textLineHeight** instead:\n> ```swift\n> SkeletonAppearance.default.textLineHeight = .relativeToFont\n> ```\n\n\n### 🎨 Custom colors\n\nYou can decide which color the skeleton is tinted with. You only need to pass as a parameter the color or gradient you want.\n\n**Using solid colors**\n```swift\nview.showSkeleton(usingColor: UIColor.gray) // Solid\n// or\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n**Using gradients**\n``` swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient) // Gradient\n```\n\nBesides, **SkeletonView** features 20 flat colors 🤙🏼\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange  ...```\n\n![](Assets/flatcolors.png)\n###### Image captured from website [https://flatuicolors.com](https://flatuicolors.com)\n\n\n### 🏃‍♀️ Animations\n\n**SkeletonView** has two built-in animations, *pulse* for solid skeletons and *sliding* for gradients.\n\nBesides, if you want to do your own skeleton animation, it's really easy.\n\n\nSkeleton provides the `showAnimatedSkeleton` function which has a ```SkeletonLayerAnimation``` closure where you can define your custom animation.\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\nYou can call the function like this:\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Customize here your animation\n\n  return animation\n}\n```\n\nIt's available ```SkeletonAnimationBuilder```. It's a builder to make ```SkeletonLayerAnimation```.\n\nToday, you can create **sliding animations** for gradients, deciding the **direction** and setting the **duration** of the animation (default = 1.5s).\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` is an enum, with theses cases:\n\n|  Direction | Preview\n|------- | -------\n| .leftRight | ![](Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](Assets/sliding_right_to_left.gif)\n| .topBottom | ![](Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 TRICK!**\n>\n> Exist another way to create sliding animations, just using this shortcut:\n> ```swift\n> let animation = GradientDirection.leftToRight.slidingAnimation()\n> ```\n\n  \n\n### 🏄 Transitions\n\n**SkeletonView** has built-in transitions to **show** or **hide** the skeletons in a *smoother* way 🤙\n\nTo use the transition, simply add the ```transition``` parameter to your ```showSkeleton()``` or ```hideSkeleton()``` function with the transition time, like this:\n\n```swift\nview.showSkeleton(transition: .crossDissolve(0.25))     //Show skeleton cross dissolve transition with 0.25 seconds fade time\nview.hideSkeleton(transition: .crossDissolve(0.25))     //Hide skeleton cross dissolve transition with 0.25 seconds fade time\n\n```\n\nThe default value is  `crossDissolve(0.25)`\n\n**Preview**\n\n<table>\n<tr>\n<td width=\"50%\">\n<center>None</center>\n</td>\n<td width=\"50%\">\n<center>Cross dissolve</center>\n</td>\n</tr>\n<tr>\n<td width=\"50%\">\n<img src=\"Assets/skeleton_transition_nofade.gif\"></img>\n</td>\n<td width=\"50%\">\n<img src=\"Assets/skeleton_transition_fade.gif\"></img>\n</td>\n</tr>\n</table>\n\n\n## ✨ Miscellaneous \n\n  \n\n**Hierarchy**\n\nSince ```SkeletonView``` is recursive, and we want skeleton to be very efficient, we want to stop recursion as soon as possible. For this reason, you must set the container view as `Skeletonable`, because Skeleton will stop looking for `skeletonable` subviews as soon as a view is not Skeletonable, breaking then the recursion.\n\nBecause an image is worth a thousand words:\n\nIn this example we have a `UIViewController` with a `ContainerView` and a `UITableView`. When the view is ready, we show the skeleton using this method:\n```\nview.showSkeleton()\n```\n\n> ```isSkeletonable```= ☠️\n\n| Configuration | Result|\n|:-------:|:-------:|\n|<img src=\"Assets/no_skeletonable.jpg\" width=\"350\"/> | <img src=\"Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"Assets/container_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"Assets/container_skeletonable.jpg\" width=\"350\"/> | <img src=\"Assets/container_skeletonable_result.png\" width=\"350\"/>|\n|<img src=\"Assets/all_skeletonables.jpg\" width=\"350\"/>| <img src=\"Assets/all_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"Assets/tableview_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"Assets/tableview_no_skeletonable_result.png\" height=\"350\"/>|\n|<img src=\"Assets/tableview_skeletonable.jpg\" width=\"350\"/> | <img src=\"Assets/tableview_skeletonable_result.png\" height=\"350\"/>|\n\n  \n\n**Skeleton views layout**\n\nSometimes skeleton layout may not fit your layout because the parent view bounds have changed. ~For example, rotating the device.~\n\nYou can relayout the skeleton views like so:\n\n```swift\noverride func viewDidLayoutSubviews() {\n    view.layoutSkeletonIfNeeded()\n}\n```\n\n> 📣 **IMPORTANT!** \n> \n> You shouldn't call this method. From **version 1.8.1** you don't need to call this method, the library does automatically. So, you can use this method **ONLY** in the cases when you need to update the layout of the skeleton manually.\n\n\n  \n\n**Update skeleton**\n\nYou can change the skeleton configuration at any time like its colour, animation, etc. with the following methods:\n\n```swift\n(1) view.updateSkeleton()                 // Solid\n(2) view.updateGradientSkeleton()         // Gradient\n(3) view.updateAnimatedSkeleton()         // Solid animated\n(4) view.updateAnimatedGradientSkeleton() // Gradient animated\n```\n\n**Hiding views when the animation starts**\n\nSometimes you wanna hide some view when the animation starts, so there is a quick property that you can use to make this happen:\n\n```swift\nview.isHiddenWhenSkeletonIsActive = true  // This works only when isSkeletonable = true\n```\n\n**Don't modify user interaction when the skeleton is active**\n\n\nBy default, the user interaction is disabled for skeletonized items, but if you don't want to modify the user interaction indicator when skeleton is active, you can use the `isUserInteractionDisabledWhenSkeletonIsActive` property:\n\n```swift\nview.isUserInteractionDisabledWhenSkeletonIsActive = false  // The view will be active when the skeleton will be active.\n```\n\n**Don't use the font line height for the skeleton lines in labels**\n\nFalse to disable skeleton to auto-adjust to font height for a `UILabel` or `UITextView`. By default, the skeleton lines height is auto-adjusted to font height to more accurately reflect the text in the label rect rather than using the bounding box.\n\n```swift\nlabel.useFontLineHeight = false\n```\n\n**Delayed show skeleton**\n\nYou can delay the presentation of the skeleton if the views update quickly.\n\n```swift\nfunc showSkeleton(usingColor: UIColor,\n                  animated: Bool,\n                  delay: TimeInterval,\n                  transition: SkeletonTransitionStyle)\n```\n\n```swift\nfunc showGradientSkeleton(usingGradient: SkeletonGradient,\n                          animated: Bool,\n                          delay: TimeInterval,\n                          transition: SkeletonTransitionStyle)\n```\n\n**Debug**\n\nTo facilitate the debug tasks when something is not working fine. **`SkeletonView`** has some new tools.\n\nFirst, `UIView` has available a property with his skeleton info:\n```swift\nvar sk.skeletonTreeDescription: String\n\n```\n\nBesides, you can activate the new **debug mode**. You just add the environment variable `SKELETON_DEBUG` and activate it.\n\n![](Assets/debug_mode.png)\n\nThen, when the skeleton appears, you can see the view hierarchy in the Xcode console.\n\n```\n{ \n  \"type\" : \"UIView\", // UITableView, UILabel...\n  \"isSkeletonable\" : true,\n  \"reference\" : \"0x000000014751ce30\",\n  \"children\" : [\n    {\n      \"type\" : \"UIView\",\n      \"isSkeletonable\" : true,\n      \"children\" : [ ... ],\n      \"reference\" : \"0x000000014751cfa0\"\n    }\n  ]\n}\n```\n  \n**Supported OS & SDK Versions**\n\n* iOS 9.0+\n* tvOS 9.0+\n* Swift 5.3\n\n## ❤️ Contributing\nThis is an open source project, so feel free to contribute. How?\n\n- Open an [issue](https://github.com/Juanpe/SkeletonView/issues/new).\n- Send feedback via [email](mailto://juanpecatalan.com).\n- Propose your own fixes, suggestions and open a pull request with the changes.\n\nSee [all contributors](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\nFor more information, please read the [contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).\n\n\n## 📢 Mentions\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)\n- [Best iOS articles, new tools & more](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)\n\n## 🏆 Sponsors\n\nOpen-source projects cannot live long without your help. If you find **SkeletonView** is useful, please consider supporting this \nproject by becoming a sponsor. \n\nBecome a sponsor through [GitHub Sponsors](https://github.com/sponsors/Juanpe) :heart:\n\n## 👨🏻‍💻 Author\n\n[Juanpe Catalán](http://www.twitter.com/JuanpeCatalan)\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n\n## 👮🏻 License\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "SkeletonVIew.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:SkeletonView.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Examples/iOS Example/iOS Example.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Examples/tvOS Example/tvOS Example.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "SkeletonVIew.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "SkeletonView.podspec",
    "content": "Pod::Spec.new do |s|\n  s.name         = \"SkeletonView\"\n  s.version      = \"1.31.0\"\n  s.summary      = \"An elegant way to show users that something is happening and also prepare them to which contents he is waiting\"\n  s.description  = <<-DESC\n  Today almost all apps have async processes, as API requests, long runing processes, etc. And while the processes are working, usually developers place a loading view to show users that something is going on.\n  SkeletonView has been conceived to address this need, an elegant way to show users that something is happening and also prepare them to which contents he is waiting.\n  DESC\n  s.homepage     = \"https://github.com/Juanpe/SkeletonView\"\n  s.license      = { :type => \"MIT\", :file => \"LICENSE\" }\n  s.author             = { \"Juanpe Catalán\" => \"juanpecm@gmail.com\" }\n  s.social_media_url   = \"https://x.com/JuanpeCatalan\"\n  s.ios.deployment_target = \"9.0\"\n  s.tvos.deployment_target = \"9.0\"\n  s.swift_version = \"5.0\"\n  s.source       = { :git => \"https://github.com/Juanpe/SkeletonView.git\", :tag => s.version.to_s }\n  s.source_files  = \"SkeletonViewCore/Sources/**/*.{swift,h}\"\nend\n"
  },
  {
    "path": "SkeletonView.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tF5225F2A278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5225F29278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift */; };\n\t\tF5225F2B278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5225F29278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift */; };\n\t\tF53D731826D399E100249D46 /* SkeletonTreeNode+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D731726D399E100249D46 /* SkeletonTreeNode+Extensions.swift */; };\n\t\tF53D731926D399E100249D46 /* SkeletonTreeNode+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D731726D399E100249D46 /* SkeletonTreeNode+Extensions.swift */; };\n\t\tF53D731B26D3A35100249D46 /* SkeletonExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D731A26D3A35100249D46 /* SkeletonExtended.swift */; };\n\t\tF53D731C26D3A35100249D46 /* SkeletonExtended.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D731A26D3A35100249D46 /* SkeletonExtended.swift */; };\n\t\tF53D731F26D3AC4000249D46 /* SkeletonTreeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F70726D38F3100A80B83 /* SkeletonTreeNode.swift */; };\n\t\tF53D732326D3C3A800249D46 /* UILabel+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D732226D3C3A800249D46 /* UILabel+SKExtensions.swift */; };\n\t\tF53D732426D3C3A800249D46 /* UILabel+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F53D732226D3C3A800249D46 /* UILabel+SKExtensions.swift */; };\n\t\tF556F56626CD1F3900A80B83 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* SkeletonAppearance.swift */; };\n\t\tF556F56726CD1F3900A80B83 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* SkeletonLayerBuilder.swift */; };\n\t\tF556F56826CD1F3900A80B83 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* SkeletonMultilineLayerBuilder.swift */; };\n\t\tF556F56926CD1F3900A80B83 /* CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* CollectionSkeleton.swift */; };\n\t\tF556F56A26CD1F3900A80B83 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SkeletonCollectionViewProtocols.swift */; };\n\t\tF556F56B26CD1F3900A80B83 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* UICollectionView+CollectionSkeleton.swift */; };\n\t\tF556F56D26CD1F3900A80B83 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* SkeletonReusableCell.swift */; };\n\t\tF556F56E26CD1F3900A80B83 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* SkeletonCollectionDataSource.swift */; };\n\t\tF556F56F26CD1F3900A80B83 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* SkeletonCollectionDelegate.swift */; };\n\t\tF556F57026CD1F3900A80B83 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* SkeletonTableViewProtocols.swift */; };\n\t\tF556F57126CD1F3900A80B83 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* UITableView+CollectionSkeleton.swift */; };\n\t\tF556F57226CD1F3900A80B83 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* UIView+CollectionSkeleton.swift */; };\n\t\tF556F57526CD1F3900A80B83 /* Int+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* Int+Extensions.swift */; };\n\t\tF556F57726CD1F3900A80B83 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* UIColor+Skeleton.swift */; };\n\t\tF556F57826CD1F3900A80B83 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* UITableView+Extensions.swift */; };\n\t\tF556F57D26CD1F3900A80B83 /* UIView+AppLifecycleNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* UIView+AppLifecycleNotifications.swift */; };\n\t\tF556F57E26CD1F3900A80B83 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_41 /* AssociationPolicy.swift */; };\n\t\tF556F58026CD1F3900A80B83 /* Recursive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_43 /* Recursive.swift */; };\n\t\tF556F58126CD1F3900A80B83 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_44 /* Swizzling.swift */; };\n\t\tF556F58526CD1F3900A80B83 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_50 /* Recoverable.swift */; };\n\t\tF556F58626CD1F3900A80B83 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* RecoverableViewState.swift */; };\n\t\tF556F58726CD1F3900A80B83 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* SkeletonAnimationBuilder.swift */; };\n\t\tF556F58826CD1F3900A80B83 /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_53 /* SkeletonConfig.swift */; };\n\t\tF556F58926CD1F3900A80B83 /* SkeletonFlowHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_54 /* SkeletonFlowHandler.swift */; };\n\t\tF556F58A26CD1F3900A80B83 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_55 /* SkeletonGradient.swift */; };\n\t\tF556F58B26CD1F3900A80B83 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_56 /* SkeletonLayer.swift */; };\n\t\tF556F58D26CD1F3900A80B83 /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_58 /* SubviewsSkeletonables.swift */; };\n\t\tF556F58E26CD1F3900A80B83 /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_60 /* SkeletonTransitionStyle.swift */; };\n\t\tF556F58F26CD1F3900A80B83 /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_61 /* UIView+Transitions.swift */; };\n\t\tF556F64D26CD2CF800A80B83 /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */; };\n\t\tF556F64E26CD2D3D00A80B83 /* SkeletonDebug.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */; };\n\t\tF556F65026CD2DFD00A80B83 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */; };\n\t\tF556F65126CD2DFD00A80B83 /* SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F64F26CD2DFD00A80B83 /* SkeletonView.swift */; };\n\t\tF556F65D26CD3E3600A80B83 /* SkeletonDebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */; };\n\t\tF556F67626CD458500A80B83 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F556F59426CD1F3900A80B83 /* SkeletonView.framework */; platformFilter = maccatalyst; };\n\t\tF556F67C26CD45A300A80B83 /* SkeletonDebugTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */; };\n\t\tF556F68026CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */; };\n\t\tF556F68126CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */; };\n\t\tF556F68326CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */; };\n\t\tF556F68426CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */; };\n\t\tF556F68726CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */; };\n\t\tF556F68826CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */; };\n\t\tF556F68A26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */; };\n\t\tF556F68B26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F68926CD4D6100A80B83 /* Notification+Extensions.swift */; };\n\t\tF556F69226CD506C00A80B83 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69126CD506C00A80B83 /* Deprecated.swift */; };\n\t\tF556F69326CD506C00A80B83 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69126CD506C00A80B83 /* Deprecated.swift */; };\n\t\tF556F69526CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */; };\n\t\tF556F69626CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */; };\n\t\tF556F69E26CD553B00A80B83 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */; };\n\t\tF556F69F26CD553B00A80B83 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F69D26CD553B00A80B83 /* UIView+Extensions.swift */; };\n\t\tF556F6A126CD566C00A80B83 /* UIView+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A026CD566C00A80B83 /* UIView+SKExtensions.swift */; };\n\t\tF556F6A226CD566C00A80B83 /* UIView+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A026CD566C00A80B83 /* UIView+SKExtensions.swift */; };\n\t\tF556F6A426CD5A9000A80B83 /* CALayer+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */; };\n\t\tF556F6A526CD5A9000A80B83 /* CALayer+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */; };\n\t\tF556F6A726CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */; };\n\t\tF556F6A826CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */; };\n\t\tF556F6AB26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */; };\n\t\tF556F6AC26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */; };\n\t\tF556F6AF26CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */; };\n\t\tF556F6B026CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */; };\n\t\tF556F6B526CE258300A80B83 /* GradientDirection+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */; };\n\t\tF556F6B626CE258300A80B83 /* GradientDirection+Animations.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */; };\n\t\tF556F6B926CE262700A80B83 /* GradientDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B826CE262700A80B83 /* GradientDirection.swift */; };\n\t\tF556F6BA26CE262700A80B83 /* GradientDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6B826CE262700A80B83 /* GradientDirection.swift */; };\n\t\tF556F6BC26CE272600A80B83 /* UILabel+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */; };\n\t\tF556F6BD26CE272600A80B83 /* UILabel+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */; };\n\t\tF556F6BF26CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */; };\n\t\tF556F6C026CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */; };\n\t\tF556F6C226CE27FD00A80B83 /* SkeletonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C126CE27FD00A80B83 /* SkeletonType.swift */; };\n\t\tF556F6C326CE27FD00A80B83 /* SkeletonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C126CE27FD00A80B83 /* SkeletonType.swift */; };\n\t\tF556F6C626CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */; };\n\t\tF556F6C726CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */; };\n\t\tF556F6C926CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */; };\n\t\tF556F6CA26CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */; };\n\t\tF556F6CC26CE2A7400A80B83 /* UITextView+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CB26CE2A7400A80B83 /* UITextView+SKExtensions.swift */; };\n\t\tF556F6CD26CE2A7400A80B83 /* UITextView+SKExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CB26CE2A7400A80B83 /* UITextView+SKExtensions.swift */; };\n\t\tF556F6CF26CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */; };\n\t\tF556F6D026CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */; };\n\t\tF556F6D926CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */; };\n\t\tF556F6DA26CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */; };\n\t\tF556F6DD26CE33CE00A80B83 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */; };\n\t\tF556F6E026CE367600A80B83 /* UIView+SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */; };\n\t\tF556F6E126CE367600A80B83 /* UIView+SkeletonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */; };\n\t\tF556F6F626CE876300A80B83 /* UIView+Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */; };\n\t\tF556F70826D38F3100A80B83 /* SkeletonTreeNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F556F70726D38F3100A80B83 /* SkeletonTreeNode.swift */; };\n\t\tF5C84884274BB6F000004D1A /* SkeletonTextLineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5C84883274BB6F000004D1A /* SkeletonTextLineHeight.swift */; };\n\t\tF5C84885274BB6F000004D1A /* SkeletonTextLineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5C84883274BB6F000004D1A /* SkeletonTextLineHeight.swift */; };\n\t\tOBJ_101 /* Int+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* Int+Extensions.swift */; };\n\t\tOBJ_103 /* UIColor+Skeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* UIColor+Skeleton.swift */; };\n\t\tOBJ_104 /* UITableView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_34 /* UITableView+Extensions.swift */; };\n\t\tOBJ_109 /* UIView+AppLifecycleNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* UIView+AppLifecycleNotifications.swift */; };\n\t\tOBJ_110 /* AssociationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_41 /* AssociationPolicy.swift */; };\n\t\tOBJ_112 /* Recursive.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_43 /* Recursive.swift */; };\n\t\tOBJ_113 /* Swizzling.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_44 /* Swizzling.swift */; };\n\t\tOBJ_117 /* Recoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_50 /* Recoverable.swift */; };\n\t\tOBJ_118 /* RecoverableViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* RecoverableViewState.swift */; };\n\t\tOBJ_119 /* SkeletonAnimationBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* SkeletonAnimationBuilder.swift */; };\n\t\tOBJ_120 /* SkeletonConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_53 /* SkeletonConfig.swift */; };\n\t\tOBJ_121 /* SkeletonFlowHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_54 /* SkeletonFlowHandler.swift */; };\n\t\tOBJ_122 /* SkeletonGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_55 /* SkeletonGradient.swift */; };\n\t\tOBJ_123 /* SkeletonLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_56 /* SkeletonLayer.swift */; };\n\t\tOBJ_125 /* SubviewsSkeletonables.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_58 /* SubviewsSkeletonables.swift */; };\n\t\tOBJ_126 /* SkeletonTransitionStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_60 /* SkeletonTransitionStyle.swift */; };\n\t\tOBJ_127 /* UIView+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_61 /* UIView+Transitions.swift */; };\n\t\tOBJ_147 /* SkeletonView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = \"SkeletonView::SkeletonView::Product\" /* SkeletonView.framework */; };\n\t\tOBJ_86 /* SkeletonAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* SkeletonAppearance.swift */; };\n\t\tOBJ_87 /* SkeletonLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* SkeletonLayerBuilder.swift */; };\n\t\tOBJ_88 /* SkeletonMultilineLayerBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* SkeletonMultilineLayerBuilder.swift */; };\n\t\tOBJ_89 /* CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_14 /* CollectionSkeleton.swift */; };\n\t\tOBJ_90 /* SkeletonCollectionViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_16 /* SkeletonCollectionViewProtocols.swift */; };\n\t\tOBJ_91 /* UICollectionView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_17 /* UICollectionView+CollectionSkeleton.swift */; };\n\t\tOBJ_93 /* SkeletonReusableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* SkeletonReusableCell.swift */; };\n\t\tOBJ_94 /* SkeletonCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* SkeletonCollectionDataSource.swift */; };\n\t\tOBJ_95 /* SkeletonCollectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* SkeletonCollectionDelegate.swift */; };\n\t\tOBJ_96 /* SkeletonTableViewProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* SkeletonTableViewProtocols.swift */; };\n\t\tOBJ_97 /* UITableView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* UITableView+CollectionSkeleton.swift */; };\n\t\tOBJ_98 /* UIView+CollectionSkeleton.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* UIView+CollectionSkeleton.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tF556F50C26CD1B1500A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = OBJ_1 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = \"SkeletonView::SkeletonView\";\n\t\t\tremoteInfo = SkeletonView;\n\t\t};\n\t\tF556F67726CD458500A80B83 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = OBJ_1 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = F556F56426CD1F3900A80B83;\n\t\t\tremoteInfo = \"SkeletonView tvOS\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t0AEC95C32AF537B600CD241A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = \"<group>\"; };\n\t\tF5225F29278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTextNumberOfLines.swift; sourceTree = \"<group>\"; };\n\t\tF53D731726D399E100249D46 /* SkeletonTreeNode+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"SkeletonTreeNode+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF53D731A26D3A35100249D46 /* SkeletonExtended.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonExtended.swift; sourceTree = \"<group>\"; };\n\t\tF53D732226D3C3A800249D46 /* UILabel+SKExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UILabel+SKExtensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F51026CD1B7900A80B83 /* SkeletonView.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SkeletonView.podspec; sourceTree = \"<group>\"; };\n\t\tF556F51126CD1B8000A80B83 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = \"<group>\"; };\n\t\tF556F51426CD1BFF00A80B83 /* README_zh.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_zh.md; path = Translations/README_zh.md; sourceTree = \"<group>\"; };\n\t\tF556F51526CD1BFF00A80B83 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = \"<group>\"; };\n\t\tF556F51626CD1BFF00A80B83 /* README_ko.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_ko.md; path = Translations/README_ko.md; sourceTree = \"<group>\"; };\n\t\tF556F51726CD1BFF00A80B83 /* README_fr.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_fr.md; path = Translations/README_fr.md; sourceTree = \"<group>\"; };\n\t\tF556F51826CD1BFF00A80B83 /* README_es.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README_es.md; path = Translations/README_es.md; sourceTree = \"<group>\"; };\n\t\tF556F51926CD1BFF00A80B83 /* README_pt-br.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = \"README_pt-br.md\"; path = \"Translations/README_pt-br.md\"; sourceTree = \"<group>\"; };\n\t\tF556F51A26CD1C1200A80B83 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = \"<group>\"; };\n\t\tF556F51B26CD1C1200A80B83 /* CODE_OF_CONDUCT.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CODE_OF_CONDUCT.md; sourceTree = \"<group>\"; };\n\t\tF556F51C26CD1C1200A80B83 /* CONTRIBUTING.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = \"<group>\"; };\n\t\tF556F51E26CD1C1C00A80B83 /* FUNDING.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = FUNDING.yml; sourceTree = \"<group>\"; };\n\t\tF556F52026CD1C1C00A80B83 /* release.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = release.yml; sourceTree = \"<group>\"; };\n\t\tF556F52126CD1C1C00A80B83 /* CD.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = CD.yml; sourceTree = \"<group>\"; };\n\t\tF556F52226CD1C1C00A80B83 /* validations.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = validations.yml; sourceTree = \"<group>\"; };\n\t\tF556F52326CD1C1C00A80B83 /* pod_lib_lint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = pod_lib_lint.yml; sourceTree = \"<group>\"; };\n\t\tF556F52426CD1C1C00A80B83 /* main.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = main.yml; sourceTree = \"<group>\"; };\n\t\tF556F52526CD1C1C00A80B83 /* release_notes.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = release_notes.yml; sourceTree = \"<group>\"; };\n\t\tF556F52626CD1C1C00A80B83 /* stale.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = stale.yml; sourceTree = \"<group>\"; };\n\t\tF556F52726CD1C1C00A80B83 /* pull_request_template.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = pull_request_template.md; sourceTree = \"<group>\"; };\n\t\tF556F52826CD1C1C00A80B83 /* release-drafter.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = \"release-drafter.yml\"; sourceTree = \"<group>\"; };\n\t\tF556F52A26CD1C1C00A80B83 /* submit-a-request.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = \"submit-a-request.md\"; sourceTree = \"<group>\"; };\n\t\tF556F52B26CD1C1C00A80B83 /* bug_report.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = bug_report.md; sourceTree = \"<group>\"; };\n\t\tF556F52C26CD1C1C00A80B83 /* feedback.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = feedback.md; sourceTree = \"<group>\"; };\n\t\tF556F56226CD1D8500A80B83 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tF556F56326CD1D8B00A80B83 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tF556F59426CD1F3900A80B83 /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDebug.swift; sourceTree = \"<group>\"; };\n\t\tF556F64F26CD2DFD00A80B83 /* SkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonView.swift; sourceTree = \"<group>\"; };\n\t\tF556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonDebugTests.swift; sourceTree = \"<group>\"; };\n\t\tF556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"SkeletonView tvOS Tests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tF556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"ProcessInfo+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+AssociatedObjects.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+IBInspectable.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F68926CD4D6100A80B83 /* Notification+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Notification+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F69126CD506C00A80B83 /* Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecated.swift; sourceTree = \"<group>\"; };\n\t\tF556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Notification+SkeletonFlow.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F69D26CD553B00A80B83 /* UIView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6A026CD566C00A80B83 /* UIView+SKExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+SKExtensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"CALayer+Animations.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"CALayer+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonMultilinesLayerConfig.swift; sourceTree = \"<group>\"; };\n\t\tF556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"DispatchQueue+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"GradientDirection+Animations.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6B826CE262700A80B83 /* GradientDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientDirection.swift; sourceTree = \"<group>\"; };\n\t\tF556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UILabel+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrepareViewForSkeleton.swift; sourceTree = \"<group>\"; };\n\t\tF556F6C126CE27FD00A80B83 /* SkeletonType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonType.swift; sourceTree = \"<group>\"; };\n\t\tF556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UILabel+IBInspectable.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UITextView+IBInspectable.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6CB26CE2A7400A80B83 /* UITextView+SKExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UITextView+SKExtensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTextNode.swift; sourceTree = \"<group>\"; };\n\t\tF556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UICollectionView+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+Swizzling.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+SkeletonView.swift\"; sourceTree = \"<group>\"; };\n\t\tF556F70726D38F3100A80B83 /* SkeletonTreeNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTreeNode.swift; sourceTree = \"<group>\"; };\n\t\tF5C84883274BB6F000004D1A /* SkeletonTextLineHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTextLineHeight.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_11 /* SkeletonLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayerBuilder.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_12 /* SkeletonMultilineLayerBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonMultilineLayerBuilder.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_14 /* CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionSkeleton.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_16 /* SkeletonCollectionViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionViewProtocols.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_17 /* UICollectionView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UICollectionView+CollectionSkeleton.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_20 /* SkeletonReusableCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonReusableCell.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_21 /* SkeletonCollectionDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDataSource.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_22 /* SkeletonCollectionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonCollectionDelegate.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_24 /* SkeletonTableViewProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTableViewProtocols.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_25 /* UITableView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UITableView+CollectionSkeleton.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_26 /* UIView+CollectionSkeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+CollectionSkeleton.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_31 /* Int+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"Int+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_33 /* UIColor+Skeleton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIColor+Skeleton.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_34 /* UITableView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UITableView+Extensions.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_39 /* UIView+AppLifecycleNotifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+AppLifecycleNotifications.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_41 /* AssociationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssociationPolicy.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_43 /* Recursive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recursive.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_44 /* Swizzling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Swizzling.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_50 /* Recoverable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recoverable.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_51 /* RecoverableViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoverableViewState.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_52 /* SkeletonAnimationBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAnimationBuilder.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_53 /* SkeletonConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonConfig.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_54 /* SkeletonFlowHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonFlowHandler.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_55 /* SkeletonGradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonGradient.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_56 /* SkeletonLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonLayer.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_58 /* SubviewsSkeletonables.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubviewsSkeletonables.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_60 /* SkeletonTransitionStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonTransitionStyle.swift; sourceTree = \"<group>\"; };\n\t\tOBJ_61 /* UIView+Transitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"UIView+Transitions.swift\"; sourceTree = \"<group>\"; };\n\t\tOBJ_9 /* SkeletonAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SkeletonAppearance.swift; sourceTree = \"<group>\"; };\n\t\t\"SkeletonView::SkeletonView::Product\" /* SkeletonView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SkeletonView.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t\"SkeletonView::SkeletonViewTests::Product\" /* SkeletonViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = SkeletonViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tF556F59026CD1F3900A80B83 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF556F66E26CD458500A80B83 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F67626CD458500A80B83 /* SkeletonView.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tOBJ_128 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tOBJ_146 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t\tOBJ_147 /* SkeletonView.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tF556F50F26CD1B6200A80B83 /* Deployment */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F51126CD1B8000A80B83 /* LICENSE */,\n\t\t\t\tF556F51026CD1B7900A80B83 /* SkeletonView.podspec */,\n\t\t\t\tOBJ_6 /* Package.swift */,\n\t\t\t);\n\t\t\tname = Deployment;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F51326CD1BED00A80B83 /* Documentation */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F51D26CD1C1C00A80B83 /* .github */,\n\t\t\t\tF556F51A26CD1C1200A80B83 /* CHANGELOG.md */,\n\t\t\t\tF556F51B26CD1C1200A80B83 /* CODE_OF_CONDUCT.md */,\n\t\t\t\tF556F51C26CD1C1200A80B83 /* CONTRIBUTING.md */,\n\t\t\t\tF556F51826CD1BFF00A80B83 /* README_es.md */,\n\t\t\t\tF556F51726CD1BFF00A80B83 /* README_fr.md */,\n\t\t\t\tF556F51626CD1BFF00A80B83 /* README_ko.md */,\n\t\t\t\tF556F51926CD1BFF00A80B83 /* README_pt-br.md */,\n\t\t\t\tF556F51426CD1BFF00A80B83 /* README_zh.md */,\n\t\t\t\tF556F51526CD1BFF00A80B83 /* README.md */,\n\t\t\t);\n\t\t\tname = Documentation;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F51D26CD1C1C00A80B83 /* .github */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F51E26CD1C1C00A80B83 /* FUNDING.yml */,\n\t\t\t\tF556F51F26CD1C1C00A80B83 /* workflows */,\n\t\t\t\tF556F52626CD1C1C00A80B83 /* stale.yml */,\n\t\t\t\tF556F52726CD1C1C00A80B83 /* pull_request_template.md */,\n\t\t\t\tF556F52826CD1C1C00A80B83 /* release-drafter.yml */,\n\t\t\t\tF556F52926CD1C1C00A80B83 /* ISSUE_TEMPLATE */,\n\t\t\t);\n\t\t\tpath = .github;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F51F26CD1C1C00A80B83 /* workflows */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F52026CD1C1C00A80B83 /* release.yml */,\n\t\t\t\tF556F52126CD1C1C00A80B83 /* CD.yml */,\n\t\t\t\tF556F52226CD1C1C00A80B83 /* validations.yml */,\n\t\t\t\tF556F52326CD1C1C00A80B83 /* pod_lib_lint.yml */,\n\t\t\t\tF556F52426CD1C1C00A80B83 /* main.yml */,\n\t\t\t\tF556F52526CD1C1C00A80B83 /* release_notes.yml */,\n\t\t\t);\n\t\t\tpath = workflows;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F52926CD1C1C00A80B83 /* ISSUE_TEMPLATE */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F52A26CD1C1C00A80B83 /* submit-a-request.md */,\n\t\t\t\tF556F52B26CD1C1C00A80B83 /* bug_report.md */,\n\t\t\t\tF556F52C26CD1C1C00A80B83 /* feedback.md */,\n\t\t\t);\n\t\t\tpath = ISSUE_TEMPLATE;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F55F26CD1D4400A80B83 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F56226CD1D8500A80B83 /* Info.plist */,\n\t\t\t\t0AEC95C32AF537B600CD241A /* PrivacyInfo.xcprivacy */,\n\t\t\t);\n\t\t\tpath = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F56026CD1D5300A80B83 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F56326CD1D8B00A80B83 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F64A26CD2CD100A80B83 /* API */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F6B226CE24DA00A80B83 /* AnimationBuilder */,\n\t\t\t\tF556F6DB26CE32DA00A80B83 /* Appearance */,\n\t\t\t\tF556F6D726CE30EE00A80B83 /* Collections */,\n\t\t\t\tF556F69126CD506C00A80B83 /* Deprecated.swift */,\n\t\t\t\tF556F68C26CD4EB400A80B83 /* FoundationExtensions */,\n\t\t\t\tF556F6B726CE25B100A80B83 /* Models */,\n\t\t\t\tF556F64F26CD2DFD00A80B83 /* SkeletonView.swift */,\n\t\t\t\tF53D731A26D3A35100249D46 /* SkeletonExtended.swift */,\n\t\t\t\tF556F68526CD49E900A80B83 /* UIKitExtensions */,\n\t\t\t);\n\t\t\tpath = API;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F64B26CD2CD600A80B83 /* Internal */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F70626D38E8300A80B83 /* SkeletonTree */,\n\t\t\t\tF556F6D326CE2F3700A80B83 /* Collections */,\n\t\t\t\tF556F65226CD2E0A00A80B83 /* Debug */,\n\t\t\t\tF556F67E26CD476300A80B83 /* FoundationExtensions */,\n\t\t\t\tF556F6AD26CE241D00A80B83 /* Helpers */,\n\t\t\t\tF556F6C426CE284300A80B83 /* Models */,\n\t\t\t\tF556F6A926CD5C3E00A80B83 /* SkeletonConfigs */,\n\t\t\t\tF556F6B326CE256D00A80B83 /* SkeletonExtensions */,\n\t\t\t\tOBJ_54 /* SkeletonFlowHandler.swift */,\n\t\t\t\tF556F6B126CE246E00A80B83 /* SkeletonLayerBuilders */,\n\t\t\t\tF556F67D26CD475800A80B83 /* UIKitExtensions */,\n\t\t\t);\n\t\t\tpath = Internal;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F65226CD2E0A00A80B83 /* Debug */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F64C26CD2CF700A80B83 /* SkeletonDebug.swift */,\n\t\t\t);\n\t\t\tpath = Debug;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F65B26CD3E1400A80B83 /* Debug */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F65C26CD3E3600A80B83 /* SkeletonDebugTests.swift */,\n\t\t\t);\n\t\t\tpath = Debug;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F67D26CD475800A80B83 /* UIKitExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F6A626CD5B0400A80B83 /* CALayer+Extensions.swift */,\n\t\t\t\tOBJ_17 /* UICollectionView+CollectionSkeleton.swift */,\n\t\t\t\tOBJ_33 /* UIColor+Skeleton.swift */,\n\t\t\t\tF556F6BB26CE272600A80B83 /* UILabel+Extensions.swift */,\n\t\t\t\tOBJ_25 /* UITableView+CollectionSkeleton.swift */,\n\t\t\t\tOBJ_34 /* UITableView+Extensions.swift */,\n\t\t\t\tOBJ_39 /* UIView+AppLifecycleNotifications.swift */,\n\t\t\t\tF556F68226CD48F700A80B83 /* UIView+AssociatedObjects.swift */,\n\t\t\t\tOBJ_26 /* UIView+CollectionSkeleton.swift */,\n\t\t\t\tF556F69D26CD553B00A80B83 /* UIView+Extensions.swift */,\n\t\t\t\tF556F6DF26CE367600A80B83 /* UIView+SkeletonView.swift */,\n\t\t\t\tF556F6DC26CE33CE00A80B83 /* UIView+Swizzling.swift */,\n\t\t\t\tOBJ_61 /* UIView+Transitions.swift */,\n\t\t\t\tF53D731726D399E100249D46 /* SkeletonTreeNode+Extensions.swift */,\n\t\t\t);\n\t\t\tpath = UIKitExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F67E26CD476300A80B83 /* FoundationExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_31 /* Int+Extensions.swift */,\n\t\t\t\tF556F67F26CD47CF00A80B83 /* ProcessInfo+Extensions.swift */,\n\t\t\t\tF556F68926CD4D6100A80B83 /* Notification+Extensions.swift */,\n\t\t\t\tF556F6AE26CE244100A80B83 /* DispatchQueue+Extensions.swift */,\n\t\t\t);\n\t\t\tpath = FoundationExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F68526CD49E900A80B83 /* UIKitExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F6A326CD5A9000A80B83 /* CALayer+Animations.swift */,\n\t\t\t\tF556F68626CD49F900A80B83 /* UIView+IBInspectable.swift */,\n\t\t\t\tF556F6A026CD566C00A80B83 /* UIView+SKExtensions.swift */,\n\t\t\t\tF556F6C526CE2A2100A80B83 /* UILabel+IBInspectable.swift */,\n\t\t\t\tF53D732226D3C3A800249D46 /* UILabel+SKExtensions.swift */,\n\t\t\t\tF556F6C826CE2A4A00A80B83 /* UITextView+IBInspectable.swift */,\n\t\t\t\tF556F6D826CE315A00A80B83 /* UICollectionView+Extensions.swift */,\n\t\t\t\tF556F6CB26CE2A7400A80B83 /* UITextView+SKExtensions.swift */,\n\t\t\t);\n\t\t\tpath = UIKitExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F68C26CD4EB400A80B83 /* FoundationExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F69426CD509E00A80B83 /* Notification+SkeletonFlow.swift */,\n\t\t\t);\n\t\t\tpath = FoundationExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6A926CD5C3E00A80B83 /* SkeletonConfigs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_53 /* SkeletonConfig.swift */,\n\t\t\t\tF556F6AA26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift */,\n\t\t\t);\n\t\t\tpath = SkeletonConfigs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6AD26CE241D00A80B83 /* Helpers */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_43 /* Recursive.swift */,\n\t\t\t\tOBJ_41 /* AssociationPolicy.swift */,\n\t\t\t\tOBJ_44 /* Swizzling.swift */,\n\t\t\t);\n\t\t\tpath = Helpers;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6B126CE246E00A80B83 /* SkeletonLayerBuilders */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_12 /* SkeletonMultilineLayerBuilder.swift */,\n\t\t\t\tOBJ_11 /* SkeletonLayerBuilder.swift */,\n\t\t\t);\n\t\t\tpath = SkeletonLayerBuilders;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6B226CE24DA00A80B83 /* AnimationBuilder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_52 /* SkeletonAnimationBuilder.swift */,\n\t\t\t);\n\t\t\tpath = AnimationBuilder;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6B326CE256D00A80B83 /* SkeletonExtensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_58 /* SubviewsSkeletonables.swift */,\n\t\t\t\tF556F6BE26CE277F00A80B83 /* PrepareViewForSkeleton.swift */,\n\t\t\t\tF556F6CE26CE2AB800A80B83 /* SkeletonTextNode.swift */,\n\t\t\t\tOBJ_50 /* Recoverable.swift */,\n\t\t\t\tF556F6B426CE258300A80B83 /* GradientDirection+Animations.swift */,\n\t\t\t);\n\t\t\tpath = SkeletonExtensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6B726CE25B100A80B83 /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_60 /* SkeletonTransitionStyle.swift */,\n\t\t\t\tOBJ_55 /* SkeletonGradient.swift */,\n\t\t\t\tF556F6B826CE262700A80B83 /* GradientDirection.swift */,\n\t\t\t\tF556F6C126CE27FD00A80B83 /* SkeletonType.swift */,\n\t\t\t\tF5C84883274BB6F000004D1A /* SkeletonTextLineHeight.swift */,\n\t\t\t\tF5225F29278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift */,\n\t\t\t);\n\t\t\tpath = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6C426CE284300A80B83 /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_56 /* SkeletonLayer.swift */,\n\t\t\t\tOBJ_51 /* RecoverableViewState.swift */,\n\t\t\t);\n\t\t\tpath = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6D326CE2F3700A80B83 /* Collections */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_21 /* SkeletonCollectionDataSource.swift */,\n\t\t\t\tOBJ_22 /* SkeletonCollectionDelegate.swift */,\n\t\t\t\tOBJ_20 /* SkeletonReusableCell.swift */,\n\t\t\t\tOBJ_14 /* CollectionSkeleton.swift */,\n\t\t\t);\n\t\t\tpath = Collections;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6D726CE30EE00A80B83 /* Collections */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_23 /* TableViews */,\n\t\t\t\tOBJ_15 /* CollectionViews */,\n\t\t\t);\n\t\t\tpath = Collections;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F6DB26CE32DA00A80B83 /* Appearance */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_9 /* SkeletonAppearance.swift */,\n\t\t\t);\n\t\t\tpath = Appearance;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tF556F70626D38E8300A80B83 /* SkeletonTree */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F70726D38F3100A80B83 /* SkeletonTreeNode.swift */,\n\t\t\t);\n\t\t\tpath = SkeletonTree;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tOBJ_15 /* CollectionViews */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_16 /* SkeletonCollectionViewProtocols.swift */,\n\t\t\t);\n\t\t\tpath = CollectionViews;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tOBJ_23 /* TableViews */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tOBJ_24 /* SkeletonTableViewProtocols.swift */,\n\t\t\t);\n\t\t\tpath = TableViews;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tOBJ_5 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F51326CD1BED00A80B83 /* Documentation */,\n\t\t\t\tF556F50F26CD1B6200A80B83 /* Deployment */,\n\t\t\t\tOBJ_7 /* Sources */,\n\t\t\t\tOBJ_62 /* Tests */,\n\t\t\t\tOBJ_64 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tOBJ_62 /* Tests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F65B26CD3E1400A80B83 /* Debug */,\n\t\t\t\tF556F56026CD1D5300A80B83 /* Supporting Files */,\n\t\t\t);\n\t\t\tname = Tests;\n\t\t\tpath = SkeletonViewCore/Tests;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n\t\tOBJ_64 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t\"SkeletonView::SkeletonView::Product\" /* SkeletonView.framework */,\n\t\t\t\t\"SkeletonView::SkeletonViewTests::Product\" /* SkeletonViewTests.xctest */,\n\t\t\t\tF556F59426CD1F3900A80B83 /* SkeletonView.framework */,\n\t\t\t\tF556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tOBJ_7 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tF556F64A26CD2CD100A80B83 /* API */,\n\t\t\t\tF556F64B26CD2CD600A80B83 /* Internal */,\n\t\t\t\tF556F55F26CD1D4400A80B83 /* Supporting Files */,\n\t\t\t);\n\t\t\tname = Sources;\n\t\t\tpath = SkeletonViewCore/Sources;\n\t\t\tsourceTree = SOURCE_ROOT;\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tF556F56426CD1F3900A80B83 /* SkeletonView tvOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F556F59126CD1F3900A80B83 /* Build configuration list for PBXNativeTarget \"SkeletonView tvOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF556F65626CD312100A80B83 /* Swiftlint */,\n\t\t\t\tF556F56526CD1F3900A80B83 /* Sources */,\n\t\t\t\tF556F59026CD1F3900A80B83 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SkeletonView tvOS\";\n\t\t\tproductName = SkeletonView;\n\t\t\tproductReference = F556F59426CD1F3900A80B83 /* SkeletonView.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tF556F67026CD458500A80B83 /* SkeletonView tvOS Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = F556F67926CD458500A80B83 /* Build configuration list for PBXNativeTarget \"SkeletonView tvOS Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF556F66D26CD458500A80B83 /* Sources */,\n\t\t\t\tF556F66E26CD458500A80B83 /* Frameworks */,\n\t\t\t\tF556F66F26CD458500A80B83 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tF556F67826CD458500A80B83 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"SkeletonView tvOS Tests\";\n\t\t\tproductName = \"SkeletonView tvOS Tests\";\n\t\t\tproductReference = F556F67126CD458500A80B83 /* SkeletonView tvOS Tests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t\"SkeletonView::SkeletonView\" /* SkeletonView iOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = OBJ_82 /* Build configuration list for PBXNativeTarget \"SkeletonView iOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tF556F65526CD311200A80B83 /* Swiftlint */,\n\t\t\t\tOBJ_85 /* Sources */,\n\t\t\t\tOBJ_128 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"SkeletonView iOS\";\n\t\t\tproductName = SkeletonView;\n\t\t\tproductReference = \"SkeletonView::SkeletonView::Product\" /* SkeletonView.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\t\"SkeletonView::SkeletonViewTests\" /* SkeletonView iOS Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = OBJ_141 /* Build configuration list for PBXNativeTarget \"SkeletonView iOS Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tOBJ_144 /* Sources */,\n\t\t\t\tOBJ_146 /* Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tOBJ_148 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"SkeletonView iOS Tests\";\n\t\t\tproductName = SkeletonViewTests;\n\t\t\tproductReference = \"SkeletonView::SkeletonViewTests::Product\" /* SkeletonViewTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tOBJ_1 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftMigration = 9999;\n\t\t\t\tLastSwiftUpdateCheck = 1250;\n\t\t\t\tLastUpgradeCheck = 9999;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tF556F67026CD458500A80B83 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 12.5.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = OBJ_2 /* Build configuration list for PBXProject \"SkeletonView\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = OBJ_5;\n\t\t\tproductRefGroup = OBJ_64 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t\"SkeletonView::SkeletonView\" /* SkeletonView iOS */,\n\t\t\t\t\"SkeletonView::SkeletonViewTests\" /* SkeletonView iOS Tests */,\n\t\t\t\tF556F56426CD1F3900A80B83 /* SkeletonView tvOS */,\n\t\t\t\tF556F67026CD458500A80B83 /* SkeletonView tvOS Tests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tF556F66F26CD458500A80B83 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\tF556F65526CD311200A80B83 /* Swiftlint */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = Swiftlint;\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"if test -d \\\"/opt/homebrew/bin/\\\"; then\\n  PATH=\\\"/opt/homebrew/bin/:${PATH}\\\"\\nfi\\n\\nexport PATH\\n\\nif which swiftlint >/dev/null; then\\n  swiftlint\\nelse\\n  echo \\\"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\\\"\\nfi\\n\";\n\t\t};\n\t\tF556F65626CD312100A80B83 /* Swiftlint */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = Swiftlint;\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"if test -d \\\"/opt/homebrew/bin/\\\"; then\\n  PATH=\\\"/opt/homebrew/bin/:${PATH}\\\"\\nfi\\n\\nexport PATH\\n\\nif which swiftlint >/dev/null; then\\n  swiftlint\\nelse\\n  echo \\\"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\\\"\\nfi\\n\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tF556F56526CD1F3900A80B83 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t\tF556F56626CD1F3900A80B83 /* SkeletonAppearance.swift in Sources */,\n\t\t\t\tF556F6CA26CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */,\n\t\t\t\tF556F6E126CE367600A80B83 /* UIView+SkeletonView.swift in Sources */,\n\t\t\t\tF556F56726CD1F3900A80B83 /* SkeletonLayerBuilder.swift in Sources */,\n\t\t\t\tF556F6D026CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */,\n\t\t\t\tF556F65126CD2DFD00A80B83 /* SkeletonView.swift in Sources */,\n\t\t\t\tF556F56826CD1F3900A80B83 /* SkeletonMultilineLayerBuilder.swift in Sources */,\n\t\t\t\tF53D731926D399E100249D46 /* SkeletonTreeNode+Extensions.swift in Sources */,\n\t\t\t\tF556F56926CD1F3900A80B83 /* CollectionSkeleton.swift in Sources */,\n\t\t\t\tF556F56A26CD1F3900A80B83 /* SkeletonCollectionViewProtocols.swift in Sources */,\n\t\t\t\tF556F6C026CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */,\n\t\t\t\tF556F6A826CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */,\n\t\t\t\tF556F56B26CD1F3900A80B83 /* UICollectionView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tF556F56D26CD1F3900A80B83 /* SkeletonReusableCell.swift in Sources */,\n\t\t\t\tF556F56E26CD1F3900A80B83 /* SkeletonCollectionDataSource.swift in Sources */,\n\t\t\t\tF556F56F26CD1F3900A80B83 /* SkeletonCollectionDelegate.swift in Sources */,\n\t\t\t\tF556F68426CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */,\n\t\t\t\tF556F6CD26CE2A7400A80B83 /* UITextView+SKExtensions.swift in Sources */,\n\t\t\t\tF556F57026CD1F3900A80B83 /* SkeletonTableViewProtocols.swift in Sources */,\n\t\t\t\tF556F57126CD1F3900A80B83 /* UITableView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tF556F57226CD1F3900A80B83 /* UIView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tF556F6BD26CE272600A80B83 /* UILabel+Extensions.swift in Sources */,\n\t\t\t\tF556F68B26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */,\n\t\t\t\tF556F57526CD1F3900A80B83 /* Int+Extensions.swift in Sources */,\n\t\t\t\tF556F57726CD1F3900A80B83 /* UIColor+Skeleton.swift in Sources */,\n\t\t\t\tF556F69626CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */,\n\t\t\t\tF556F57826CD1F3900A80B83 /* UITableView+Extensions.swift in Sources */,\n\t\t\t\tF556F57D26CD1F3900A80B83 /* UIView+AppLifecycleNotifications.swift in Sources */,\n\t\t\t\tF556F57E26CD1F3900A80B83 /* AssociationPolicy.swift in Sources */,\n\t\t\t\tF556F6B026CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */,\n\t\t\t\tF556F58026CD1F3900A80B83 /* Recursive.swift in Sources */,\n\t\t\t\tF53D731C26D3A35100249D46 /* SkeletonExtended.swift in Sources */,\n\t\t\t\tF556F6F626CE876300A80B83 /* UIView+Swizzling.swift in Sources */,\n\t\t\t\tF556F58126CD1F3900A80B83 /* Swizzling.swift in Sources */,\n\t\t\t\tF53D732426D3C3A800249D46 /* UILabel+SKExtensions.swift in Sources */,\n\t\t\t\tF556F6B626CE258300A80B83 /* GradientDirection+Animations.swift in Sources */,\n\t\t\t\tF556F69F26CD553B00A80B83 /* UIView+Extensions.swift in Sources */,\n\t\t\t\tF556F58526CD1F3900A80B83 /* Recoverable.swift in Sources */,\n\t\t\t\tF5C84885274BB6F000004D1A /* SkeletonTextLineHeight.swift in Sources */,\n\t\t\t\tF556F58626CD1F3900A80B83 /* RecoverableViewState.swift in Sources */,\n\t\t\t\tF556F58726CD1F3900A80B83 /* SkeletonAnimationBuilder.swift in Sources */,\n\t\t\t\tF556F58826CD1F3900A80B83 /* SkeletonConfig.swift in Sources */,\n\t\t\t\tF556F58926CD1F3900A80B83 /* SkeletonFlowHandler.swift in Sources */,\n\t\t\t\tF556F58A26CD1F3900A80B83 /* SkeletonGradient.swift in Sources */,\n\t\t\t\tF556F6C326CE27FD00A80B83 /* SkeletonType.swift in Sources */,\n\t\t\t\tF556F58B26CD1F3900A80B83 /* SkeletonLayer.swift in Sources */,\n\t\t\t\tF5225F2B278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift in Sources */,\n\t\t\t\tF556F6A226CD566C00A80B83 /* UIView+SKExtensions.swift in Sources */,\n\t\t\t\tF556F69326CD506C00A80B83 /* Deprecated.swift in Sources */,\n\t\t\t\tF556F6BA26CE262700A80B83 /* GradientDirection.swift in Sources */,\n\t\t\t\tF556F58D26CD1F3900A80B83 /* SubviewsSkeletonables.swift in Sources */,\n\t\t\t\tF556F58E26CD1F3900A80B83 /* SkeletonTransitionStyle.swift in Sources */,\n\t\t\t\tF556F6AC26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */,\n\t\t\t\tF53D731F26D3AC4000249D46 /* SkeletonTreeNode.swift in Sources */,\n\t\t\t\tF556F68126CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */,\n\t\t\t\tF556F68826CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */,\n\t\t\t\tF556F6C726CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */,\n\t\t\t\tF556F6DA26CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */,\n\t\t\t\tF556F64E26CD2D3D00A80B83 /* SkeletonDebug.swift in Sources */,\n\t\t\t\tF556F6A526CD5A9000A80B83 /* CALayer+Animations.swift in Sources */,\n\t\t\t\tF556F58F26CD1F3900A80B83 /* UIView+Transitions.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tF556F66D26CD458500A80B83 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tF556F67C26CD45A300A80B83 /* SkeletonDebugTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tOBJ_144 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t\tF556F65D26CD3E3600A80B83 /* SkeletonDebugTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tOBJ_85 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 0;\n\t\t\tfiles = (\n\t\t\t\tOBJ_86 /* SkeletonAppearance.swift in Sources */,\n\t\t\t\tF556F6C926CE2A4A00A80B83 /* UITextView+IBInspectable.swift in Sources */,\n\t\t\t\tOBJ_87 /* SkeletonLayerBuilder.swift in Sources */,\n\t\t\t\tF556F6CF26CE2AB800A80B83 /* SkeletonTextNode.swift in Sources */,\n\t\t\t\tF556F65026CD2DFD00A80B83 /* SkeletonView.swift in Sources */,\n\t\t\t\tOBJ_88 /* SkeletonMultilineLayerBuilder.swift in Sources */,\n\t\t\t\tF53D731B26D3A35100249D46 /* SkeletonExtended.swift in Sources */,\n\t\t\t\tOBJ_89 /* CollectionSkeleton.swift in Sources */,\n\t\t\t\tOBJ_90 /* SkeletonCollectionViewProtocols.swift in Sources */,\n\t\t\t\tF556F6BF26CE277F00A80B83 /* PrepareViewForSkeleton.swift in Sources */,\n\t\t\t\tF556F6A726CD5B0400A80B83 /* CALayer+Extensions.swift in Sources */,\n\t\t\t\tOBJ_91 /* UICollectionView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tOBJ_93 /* SkeletonReusableCell.swift in Sources */,\n\t\t\t\tOBJ_94 /* SkeletonCollectionDataSource.swift in Sources */,\n\t\t\t\tOBJ_95 /* SkeletonCollectionDelegate.swift in Sources */,\n\t\t\t\tF556F68326CD48F700A80B83 /* UIView+AssociatedObjects.swift in Sources */,\n\t\t\t\tF556F6CC26CE2A7400A80B83 /* UITextView+SKExtensions.swift in Sources */,\n\t\t\t\tOBJ_96 /* SkeletonTableViewProtocols.swift in Sources */,\n\t\t\t\tOBJ_97 /* UITableView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tOBJ_98 /* UIView+CollectionSkeleton.swift in Sources */,\n\t\t\t\tF556F6BC26CE272600A80B83 /* UILabel+Extensions.swift in Sources */,\n\t\t\t\tF556F68A26CD4D6100A80B83 /* Notification+Extensions.swift in Sources */,\n\t\t\t\tOBJ_101 /* Int+Extensions.swift in Sources */,\n\t\t\t\tOBJ_103 /* UIColor+Skeleton.swift in Sources */,\n\t\t\t\tF556F69526CD509E00A80B83 /* Notification+SkeletonFlow.swift in Sources */,\n\t\t\t\tOBJ_104 /* UITableView+Extensions.swift in Sources */,\n\t\t\t\tOBJ_109 /* UIView+AppLifecycleNotifications.swift in Sources */,\n\t\t\t\tOBJ_110 /* AssociationPolicy.swift in Sources */,\n\t\t\t\tF556F6AF26CE244100A80B83 /* DispatchQueue+Extensions.swift in Sources */,\n\t\t\t\tF53D731826D399E100249D46 /* SkeletonTreeNode+Extensions.swift in Sources */,\n\t\t\t\tOBJ_112 /* Recursive.swift in Sources */,\n\t\t\t\tF556F70826D38F3100A80B83 /* SkeletonTreeNode.swift in Sources */,\n\t\t\t\tOBJ_113 /* Swizzling.swift in Sources */,\n\t\t\t\tF556F6B526CE258300A80B83 /* GradientDirection+Animations.swift in Sources */,\n\t\t\t\tF53D732326D3C3A800249D46 /* UILabel+SKExtensions.swift in Sources */,\n\t\t\t\tF556F69E26CD553B00A80B83 /* UIView+Extensions.swift in Sources */,\n\t\t\t\tOBJ_117 /* Recoverable.swift in Sources */,\n\t\t\t\tOBJ_118 /* RecoverableViewState.swift in Sources */,\n\t\t\t\tF5C84884274BB6F000004D1A /* SkeletonTextLineHeight.swift in Sources */,\n\t\t\t\tOBJ_119 /* SkeletonAnimationBuilder.swift in Sources */,\n\t\t\t\tOBJ_120 /* SkeletonConfig.swift in Sources */,\n\t\t\t\tOBJ_121 /* SkeletonFlowHandler.swift in Sources */,\n\t\t\t\tOBJ_122 /* SkeletonGradient.swift in Sources */,\n\t\t\t\tF556F6C226CE27FD00A80B83 /* SkeletonType.swift in Sources */,\n\t\t\t\tOBJ_123 /* SkeletonLayer.swift in Sources */,\n\t\t\t\tF556F6E026CE367600A80B83 /* UIView+SkeletonView.swift in Sources */,\n\t\t\t\tF5225F2A278C2BCE0061A9B0 /* SkeletonTextNumberOfLines.swift in Sources */,\n\t\t\t\tF556F6A126CD566C00A80B83 /* UIView+SKExtensions.swift in Sources */,\n\t\t\t\tF556F69226CD506C00A80B83 /* Deprecated.swift in Sources */,\n\t\t\t\tF556F6B926CE262700A80B83 /* GradientDirection.swift in Sources */,\n\t\t\t\tOBJ_125 /* SubviewsSkeletonables.swift in Sources */,\n\t\t\t\tOBJ_126 /* SkeletonTransitionStyle.swift in Sources */,\n\t\t\t\tF556F6AB26CD5C4900A80B83 /* SkeletonMultilinesLayerConfig.swift in Sources */,\n\t\t\t\tF556F68026CD47CF00A80B83 /* ProcessInfo+Extensions.swift in Sources */,\n\t\t\t\tF556F68726CD49F900A80B83 /* UIView+IBInspectable.swift in Sources */,\n\t\t\t\tF556F6C626CE2A2100A80B83 /* UILabel+IBInspectable.swift in Sources */,\n\t\t\t\tF556F6D926CE315A00A80B83 /* UICollectionView+Extensions.swift in Sources */,\n\t\t\t\tF556F6DD26CE33CE00A80B83 /* UIView+Swizzling.swift in Sources */,\n\t\t\t\tF556F64D26CD2CF800A80B83 /* SkeletonDebug.swift in Sources */,\n\t\t\t\tF556F6A426CD5A9000A80B83 /* CALayer+Animations.swift in Sources */,\n\t\t\t\tOBJ_127 /* UIView+Transitions.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tF556F67826CD458500A80B83 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tplatformFilter = maccatalyst;\n\t\t\ttarget = F556F56426CD1F3900A80B83 /* SkeletonView tvOS */;\n\t\t\ttargetProxy = F556F67726CD458500A80B83 /* PBXContainerItemProxy */;\n\t\t};\n\t\tOBJ_148 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = \"SkeletonView::SkeletonView\" /* SkeletonView iOS */;\n\t\t\ttargetProxy = F556F50C26CD1B1500A80B83 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\tF556F59226CD1F3900A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Sources/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = SkeletonView;\n\t\t\t\tPRODUCT_MODULE_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"appletvsimulator appletvos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTARGET_NAME = SkeletonView;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 2.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F59326CD1F3900A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Sources/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = SkeletonView;\n\t\t\t\tPRODUCT_MODULE_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"appletvsimulator appletvos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTARGET_NAME = SkeletonView;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 2.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tF556F67A26CD458500A80B83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Tests/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.SkeletonView-tvOS-Tests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSUPPORTED_PLATFORMS = \"appletvsimulator appletvos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF556F67B26CD458500A80B83 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Tests/Supporting Files/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"com.skeletonview.SkeletonView-tvOS-Tests\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = appletvos;\n\t\t\t\tSUPPORTED_PLATFORMS = \"appletvsimulator appletvos\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = 3;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tOBJ_142 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tEMBEDDED_CONTENT_CONTAINS_SWIFT = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Tests/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.15;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphonesimulator iphoneos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTARGET_NAME = SkeletonViewTests;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tOBJ_143 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tEMBEDDED_CONTENT_CONTAINS_SWIFT = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Tests/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 14.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.15;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphonesimulator iphoneos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTARGET_NAME = SkeletonViewTests;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 7.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tOBJ_3 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tENABLE_NS_ASSERTIONS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"SWIFT_PACKAGE=1\",\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t);\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited) -DXcode\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSUPPORTED_PLATFORMS = macosx;\n\t\t\t\tSUPPORTS_MACCATALYST = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) SWIFT_PACKAGE DEBUG\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tUSE_HEADERMAP = NO;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tOBJ_4 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = s;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"SWIFT_PACKAGE=1\",\n\t\t\t\t);\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited) -DXcode\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSUPPORTED_PLATFORMS = macosx;\n\t\t\t\tSUPPORTS_MACCATALYST = YES;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited) SWIFT_PACKAGE\";\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tUSE_HEADERMAP = NO;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tOBJ_83 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Sources/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = SkeletonView;\n\t\t\t\tPRODUCT_MODULE_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphonesimulator iphoneos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTARGET_NAME = SkeletonView;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 2.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tOBJ_84 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t);\n\t\t\t\tHEADER_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tINFOPLIST_FILE = \"SkeletonViewCore/Sources/Supporting Files/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(TOOLCHAIN_DIR)/usr/lib/swift/macosx\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tOTHER_CFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_LDFLAGS = \"$(inherited)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"$(inherited)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = SkeletonView;\n\t\t\t\tPRODUCT_MODULE_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphonesimulator iphoneos\";\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = \"$(inherited)\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tTARGET_NAME = SkeletonView;\n\t\t\t\tTVOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tWATCHOS_DEPLOYMENT_TARGET = 2.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tF556F59126CD1F3900A80B83 /* Build configuration list for PBXNativeTarget \"SkeletonView tvOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F59226CD1F3900A80B83 /* Debug */,\n\t\t\t\tF556F59326CD1F3900A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tF556F67926CD458500A80B83 /* Build configuration list for PBXNativeTarget \"SkeletonView tvOS Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF556F67A26CD458500A80B83 /* Debug */,\n\t\t\t\tF556F67B26CD458500A80B83 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tOBJ_141 /* Build configuration list for PBXNativeTarget \"SkeletonView iOS Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tOBJ_142 /* Debug */,\n\t\t\t\tOBJ_143 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tOBJ_2 /* Build configuration list for PBXProject \"SkeletonView\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tOBJ_3 /* Debug */,\n\t\t\t\tOBJ_4 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tOBJ_82 /* Build configuration list for PBXNativeTarget \"SkeletonView iOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tOBJ_83 /* Debug */,\n\t\t\t\tOBJ_84 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = OBJ_1 /* Project object */;\n}\n"
  },
  {
    "path": "SkeletonView.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>"
  },
  {
    "path": "SkeletonView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "SkeletonView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>\n    <false/>\n</dict>\n</plist>"
  },
  {
    "path": "SkeletonView.xcodeproj/xcshareddata/IDETemplateMacros.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>FILEHEADER</key>\n\t<string>\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the &quot;License&quot;);\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  ___FILENAME___\n//\n//  Created by ___FULLUSERNAME___ on ___DATE___.</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView iOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1300\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"SkeletonView::SkeletonView\"\n               BuildableName = \"SkeletonView.framework\"\n               BlueprintName = \"SkeletonView iOS\"\n               ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"SkeletonView::SkeletonViewTests\"\n               BuildableName = \"SkeletonViewTests.xctest\"\n               BlueprintName = \"SkeletonView iOS Tests\"\n               ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SkeletonView.xcodeproj/xcshareddata/xcschemes/SkeletonView tvOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1300\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F556F56426CD1F3900A80B83\"\n               BuildableName = \"SkeletonView.framework\"\n               BlueprintName = \"SkeletonView tvOS\"\n               ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"NO\"\n            buildForProfiling = \"NO\"\n            buildForArchiving = \"NO\"\n            buildForAnalyzing = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F556F67026CD458500A80B83\"\n               BuildableName = \"SkeletonView tvOS Tests.xctest\"\n               BlueprintName = \"SkeletonView tvOS Tests\"\n               ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"F556F67026CD458500A80B83\"\n               BuildableName = \"SkeletonView tvOS Tests.xctest\"\n               BlueprintName = \"SkeletonView tvOS Tests\"\n               ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"F556F56426CD1F3900A80B83\"\n            BuildableName = \"SkeletonView.framework\"\n            BlueprintName = \"SkeletonView tvOS\"\n            ReferencedContainer = \"container:SkeletonView.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/AnimationBuilder/SkeletonAnimationBuilder.swift",
    "content": "//\n//  SkeletonAnimationBuilder.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 17/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n\npublic class SkeletonAnimationBuilder {\n    \n    public init() { }\n    \n    public func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {\n        { _ in\n            let startPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.startPoint))\n            startPointAnim.fromValue = direction.startPoint.from\n            startPointAnim.toValue = direction.startPoint.to\n            \n            let endPointAnim = CABasicAnimation(keyPath: #keyPath(CAGradientLayer.endPoint))\n            endPointAnim.fromValue = direction.endPoint.from\n            endPointAnim.toValue = direction.endPoint.to\n            \n            let animGroup = CAAnimationGroup()\n            animGroup.animations = [startPointAnim, endPointAnim]\n            animGroup.duration = duration\n            animGroup.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)\n            animGroup.repeatCount = .infinity\n            animGroup.autoreverses = autoreverses\n            animGroup.isRemovedOnCompletion = false\n            \n            return animGroup\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Appearance/SkeletonAppearance.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonAppearance.swift\n//\n\nimport UIKit\n\npublic enum SkeletonAppearance {\n    public static var `default` = SkeletonViewAppearance.shared\n}\n\n// codebeat:disable[TOO_MANY_IVARS]\npublic class SkeletonViewAppearance {\n    \n    static var shared = SkeletonViewAppearance()\n\n    public var tintColor: UIColor = .skeletonDefault\n\n    public var gradient = SkeletonGradient(baseColor: .skeletonDefault)\n\n    public var multilineHeight: CGFloat = 15\n    \n    public lazy var textLineHeight: SkeletonTextLineHeight = .fixed(SkeletonAppearance.default.multilineHeight)\n    \n    public var multilineSpacing: CGFloat = 10\n\n    public var multilineLastLineFillPercent: Int = 70\n\n    public var multilineCornerRadius: Int = 0\n\n    public var renderSingleLineAsView: Bool = false\n    \n    public var skeletonCornerRadius: Float = 0\n\n}\n// codebeat:enable[TOO_MANY_IVARS]\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Collections/CollectionViews/SkeletonCollectionViewProtocols.swift",
    "content": "//\n//  SkeletonCollectionViewProtocols.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 06/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier?\n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell?\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)\n}\n\npublic extension SkeletonCollectionViewDataSource {\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        UICollectionView.automaticNumberOfSkeletonItems\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? {\n        nil\n    }\n    \n    func numSections(in collectionSkeletonView: UICollectionView) -> Int {\n        1\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell? {\n        nil\n    }\n\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath) { }\n\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath) { }\n}\n\npublic protocol SkeletonCollectionViewDelegate: UICollectionViewDelegate { }\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Collections/TableViews/SkeletonTableViewProtocols.swift",
    "content": "//\n//  SkeletonTableViewProtocols.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 06/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nextension UITableView {\n    public static let automaticNumberOfSkeletonRows = -1\n}\n\npublic typealias ReusableHeaderFooterIdentifier = String\n\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell?\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)\n}\n\npublic extension SkeletonTableViewDataSource {\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        return UITableView.automaticNumberOfSkeletonRows\n    }\n    \n    func numSections(in collectionSkeletonView: UITableView) -> Int { return 1 }\n\n    /// Keeping the misspelled version around until it can be deprecated\n    /// Right now, it just calls the new correctly spelled method and returns its result\n    @available(*, deprecated, renamed: \"collectionSkeletonView(_:cellIdentifierForRowAt:)\")\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdenfierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n        return collectionSkeletonView(skeletonView, cellIdentifierForRowAt: indexPath)\n    }\n    \n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {\n        nil\n    }\n\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) { }\n}\n\npublic protocol SkeletonTableViewDelegate: UITableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier?\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier?\n}\n\npublic extension SkeletonTableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? {\n        return nil\n    }\n\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? {\n        return nil\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Deprecated.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  Deprecated.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\npublic extension Notification.Name {\n    \n    @available(*, deprecated, renamed: \"skeletonWillAppear\")\n    static let willBeginShowingSkeletons = Notification.Name.skeletonWillAppearNotification\n    \n    @available(*, deprecated, renamed: \"skeletonDidAppear\")\n    static let didShowSkeletons = Notification.Name.skeletonDidAppearNotification\n    \n    @available(*, deprecated, renamed: \"skeletonWillUpdate\")\n    static let willBeginUpdatingSkeletons = Notification.Name.skeletonWillUpdateNotification\n    \n    @available(*, deprecated, renamed: \"skeletonDidUpdate\")\n    static let didUpdateSkeletons = Notification.Name.skeletonDidUpdateNotification\n    \n    @available(*, deprecated, renamed: \"skeletonWillDisappear\")\n    static let willBeginHidingSkeletons = Notification.Name.skeletonWillDisappearNotification\n    \n    @available(*, deprecated, renamed: \"skeletonDidDisappear\")\n    static let didHideSkeletons = Notification.Name.skeletonDidDisappearNotification\n    \n}\n\npublic extension UIView {\n    \n    @available(*, deprecated, renamed: \"sk.treeNodesDescription\")\n    var skeletonDescription: String {\n        sk.skeletonTreeDescription\n    }\n    \n    @available(*, deprecated, renamed: \"sk.isSkeletonActive\")\n    var isSkeletonActive: Bool {\n        sk.isSkeletonActive\n    }\n    \n}\n\npublic extension UILabel {\n    \n    @IBInspectable\n    @available(*, deprecated, renamed: \"skeletonTextLineHeight\")\n    var useFontLineHeight: Bool {\n        get {\n            textLineHeight == .relativeToFont\n        }\n        set {\n            textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)\n        }\n    }\n    \n}\n\npublic extension UITextView {\n    \n    @IBInspectable\n    @available(*, deprecated, renamed: \"skeletonTextLineHeight\")\n    var useFontLineHeight: Bool {\n        get {\n            textLineHeight == .relativeToFont\n        }\n        set {\n            textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)\n        }\n    }\n    \n}\n\npublic extension SkeletonViewAppearance {\n    \n    @available(*, deprecated, renamed: \"textLineHeight\")\n    var useFontLineHeight: Bool {\n        get {\n            textLineHeight == .relativeToFont\n        }\n        set {\n            textLineHeight = newValue ? .relativeToFont : .fixed(SkeletonAppearance.default.multilineHeight)\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/FoundationExtensions/Notification+SkeletonFlow.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  Notification+SkeletonFlow.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport Foundation\n\npublic extension Notification.Name {\n    \n    static let skeletonWillAppearNotification = Notification.Name(\"skeletonWillAppear\")\n    static let skeletonDidAppearNotification = Notification.Name(\"skeletonDidAppear\")\n    static let skeletonWillUpdateNotification = Notification.Name(\"skeletonWillUpdate\")\n    static let skeletonDidUpdateNotification = Notification.Name(\"skeletonDidUpdate\")\n    static let skeletonWillDisappearNotification = Notification.Name(\"skeletonWillDisappear\")\n    static let skeletonDidDisappearNotification = Notification.Name(\"skeletonDidDisappear\")\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/GradientDirection.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  GradientDirection.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic enum GradientDirection {\n    \n    case leftRight\n    case rightLeft\n    case topBottom\n    case bottomTop\n    case topLeftBottomRight\n    case bottomRightTopLeft\n    \n    public func slidingAnimation(duration: CFTimeInterval = 1.5, autoreverses: Bool = false) -> SkeletonLayerAnimation {\n        return SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: self, duration: duration, autoreverses: autoreverses)\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/SkeletonGradient.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonGradient.swift\n//\n//  Created by Juanpe Catalán on 05/11/2017.\n\nimport UIKit\n\npublic struct SkeletonGradient {\n    \n    private let gradientColors: [UIColor]\n    \n    public var colors: [UIColor] {\n        return gradientColors\n    }\n    \n    public init(baseColor: UIColor, secondaryColor: UIColor? = nil) {\n        if let secondary = secondaryColor {\n            self.gradientColors = [baseColor, secondary, baseColor]\n        } else {\n            self.gradientColors = baseColor.makeGradient()\n        }\n    }\n    \n    public init(colors: [UIColor]) {\n        self.gradientColors = colors\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/SkeletonTextLineHeight.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonTextLineHeight.swift\n//\n//  Created by Juanpe Catalán on 22/11/21.\n\nimport UIKit\n\npublic enum SkeletonTextLineHeight: Equatable {\n    \n    /// Calculates the line height based on the font line height.\n    case relativeToFont\n    \n    /// Calculates the line height based on the height constraints.\n    ///\n    /// If no constraints exist, the height will be set to the `multilineHeight`\n    /// value defined in the `SkeletonAppearance`.\n    case relativeToConstraints\n    \n    /// Returns the specific height specified as the associated value.\n    case fixed(CGFloat)\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/SkeletonTextNumberOfLines.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonTextNumberOfLines.swift\n//\n//  Created by Juanpe Catalán on 10/1/22.\n\nimport UIKit\n\npublic enum SkeletonTextNumberOfLines: Equatable, ExpressibleByIntegerLiteral {\n    \n    /// Returns `numberOfLines` value.\n    case inherited\n    \n    /// Returns the specific number of lines specified as the associated value.\n    case custom(Int)\n    \n}\n\npublic extension SkeletonTextNumberOfLines {\n    \n    init(integerLiteral value: Int) {\n        self = .custom(value)\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/SkeletonTransitionStyle.swift",
    "content": "// Copyright © 2019 SkeletonView. All rights reserved.\n\nimport UIKit\n\npublic enum SkeletonTransitionStyle: Equatable {\n    case none\n    case crossDissolve(TimeInterval)\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/Models/SkeletonType.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonType.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic enum SkeletonType {\n    \n    case solid\n    case gradient\n    \n    var layer: CALayer {\n        switch self {\n        case .solid:\n            return CALayer()\n        case .gradient:\n            return CAGradientLayer()\n        }\n    }\n    \n    func defaultLayerAnimation(isRTL: Bool) -> SkeletonLayerAnimation {\n        switch self {\n        case .solid:\n            return { $0.pulse }\n        case .gradient:\n            return { SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: isRTL ? .rightLeft : .leftRight) }()\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/SkeletonExtended.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonExtended.swift\n//\n//  Created by Juanpe Catalán on 23/8/21.\n\nimport Foundation\n\n/// Type that acts as a generic extension point for all `SkeletonViewExtended` types.\npublic struct SkeletonViewExtension<ExtendedType> {\n    /// Stores the type or meta-type of any extended type.\n    public private(set) var type: ExtendedType\n\n    /// Create an instance from the provided value.\n    ///\n    /// - Parameter type: Instance being extended.\n    public init(_ type: ExtendedType) {\n        self.type = type\n    }\n}\n\n/// Protocol describing the `sk` extension points for SkeletonView extended types.\npublic protocol SkeletonViewExtended {\n    /// Type being extended.\n    associatedtype ExtendedType\n\n    /// Instance SkeletonView extension point.\n    var sk: SkeletonViewExtension<ExtendedType> { get set }\n}\n\nextension SkeletonViewExtended {\n    /// Instance SkeletonView extension point.\n    public var sk: SkeletonViewExtension<Self> {\n        get { SkeletonViewExtension(self) }\n        // swiftlint:disable:next unused_setter_value\n        set {}\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/SkeletonView.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  PublicSkeletonView.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\npublic extension UIView {\n    /// Shows the skeleton without animation using the view that calls this method as root view.\n    ///\n    /// - Parameters:\n    ///   - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        let config = SkeletonConfig(type: .solid, colors: [color], transition: transition)\n        showSkeleton(skeletonConfig: config)\n    }\n    \n    /// Shows the skeleton using the view that calls this method as root view.\n    ///\n    /// - Parameters:\n    ///   - color: The color of the skeleton. Defaults to `SkeletonAppearance.default.tintColor`.\n    ///   - animated: If the skeleton is animated or not. Defaults to `true`.\n    ///   - delay: The amount of time (measured in seconds) to wait before show the skeleton.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animated: Bool = true, delay: TimeInterval, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        \n        _delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in\n            let config = SkeletonConfig(type: .solid, colors: [color], animated: animated, transition: transition)\n            self?.showSkeleton(skeletonConfig: config)\n        }\n        \n        DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: _delayedShowSkeletonWorkItem!)\n    }\n    \n    /// Shows the gradient skeleton without animation using the view that calls this method as root view.\n    ///\n    /// - Parameters:\n    ///   - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        let config = SkeletonConfig(type: .gradient, colors: gradient.colors, transition: transition)\n        showSkeleton(skeletonConfig: config)\n    }\n    \n    /// Shows the gradient skeleton using the view that calls this method as root view.\n    ///\n    /// - Parameters:\n    ///   - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.\n    ///   - animated: If the skeleton is animated or not. Defaults to `true`.\n    ///   - delay: The amount of time (measured in seconds) to wait before show the skeleton.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showGradientSkeleton(\n        usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient,\n        animated: Bool = true,\n        delay: TimeInterval,\n        transition: SkeletonTransitionStyle = .crossDissolve(0.25)\n    ) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        \n        _delayedShowSkeletonWorkItem = DispatchWorkItem { [weak self] in\n            let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: animated, transition: transition)\n            self?.showSkeleton(skeletonConfig: config)\n        }\n        \n        DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: _delayedShowSkeletonWorkItem!)\n    }\n    \n    /// Shows the animated skeleton using the view that calls this method as root view.\n    ///\n    /// If animation is nil, sliding animation will be used, with direction left to right.\n    ///\n    /// - Parameters:\n    ///   - color: The color of skeleton. Defaults to `SkeletonAppearance.default.tintColor`.\n    ///   - animation: The animation of the skeleton. Defaults to `nil`.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation, transition: transition)\n        showSkeleton(skeletonConfig: config)\n    }\n    \n    /// Shows the gradient skeleton without animation using the view that calls this method as root view.\n    ///\n    /// If animation is nil, sliding animation will be used, with direction left to right.\n    ///\n    /// - Parameters:\n    ///   - gradient: The gradient of the skeleton. Defaults to `SkeletonAppearance.default.gradient`.\n    ///   - animation: The animation of the skeleton. Defaults to `nil`.\n    ///   - transition: The style of the transition when the skeleton appears. Defaults to `.crossDissolve(0.25)`.\n    func showAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation, transition: transition)\n        showSkeleton(skeletonConfig: config)\n    }\n\n    func updateSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor) {\n        let config = SkeletonConfig(type: .solid, colors: [color])\n        updateSkeleton(skeletonConfig: config)\n    }\n\n    func updateGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient) {\n        let config = SkeletonConfig(type: .gradient, colors: gradient.colors)\n        updateSkeleton(skeletonConfig: config)\n    }\n\n    func updateAnimatedSkeleton(usingColor color: UIColor = SkeletonAppearance.default.tintColor, animation: SkeletonLayerAnimation? = nil) {\n        let config = SkeletonConfig(type: .solid, colors: [color], animated: true, animation: animation)\n        updateSkeleton(skeletonConfig: config)\n    }\n\n    func updateAnimatedGradientSkeleton(usingGradient gradient: SkeletonGradient = SkeletonAppearance.default.gradient, animation: SkeletonLayerAnimation? = nil) {\n        let config = SkeletonConfig(type: .gradient, colors: gradient.colors, animated: true, animation: animation)\n        updateSkeleton(skeletonConfig: config)\n    }\n\n    func layoutSkeletonIfNeeded() {\n        _flowDelegate?.willBeginLayingSkeletonsIfNeeded(rootView: self)\n        recursiveLayoutSkeletonIfNeeded(root: self)\n    }\n    \n    func hideSkeleton(reloadDataAfter reload: Bool = true, transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        _delayedShowSkeletonWorkItem?.cancel()\n        _flowDelegate?.willBeginHidingSkeletons(rootView: self)\n        recursiveHideSkeleton(reloadDataAfter: reload, transition: transition, root: self)\n    }\n    \n    func startSkeletonAnimation(_ anim: SkeletonLayerAnimation? = nil) {\n        subviewsSkeletonables.recursiveSearch(leafBlock: startSkeletonLayerAnimationBlock(anim)) { subview in\n            subview.startSkeletonAnimation(anim)\n        }\n    }\n\n    func stopSkeletonAnimation() {\n        subviewsSkeletonables.recursiveSearch(leafBlock: stopSkeletonLayerAnimationBlock) { subview in\n            subview.stopSkeletonAnimation()\n        }\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/CALayer+Animations.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  CALayer+Animations.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\npublic extension CALayer {\n    \n    var pulse: CAAnimation {\n        let pulseAnimation = CABasicAnimation(keyPath: #keyPath(CALayer.backgroundColor))\n        pulseAnimation.fromValue = backgroundColor\n        \n        // swiftlint:disable:next force_unwrapping\n        pulseAnimation.toValue = UIColor(cgColor: backgroundColor!).complementaryColor.cgColor\n        pulseAnimation.duration = 1\n        pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)\n        pulseAnimation.autoreverses = true\n        pulseAnimation.repeatCount = .infinity\n        pulseAnimation.isRemovedOnCompletion = false\n        return pulseAnimation\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UICollectionView+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UICollectionView+Extensions.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic extension UICollectionView {\n    \n    static let automaticNumberOfSkeletonItems = -1\n    \n    func prepareSkeleton(completion: @escaping (Bool) -> Void) {\n        guard let originalDataSource = self.dataSource as? SkeletonCollectionViewDataSource,\n            !(originalDataSource is SkeletonCollectionDataSource)\n            else { return }\n        \n        let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource, rowHeight: 0.0)\n        self.skeletonDataSource = dataSource\n        performBatchUpdates({\n            self.reloadData()\n        }) { done in\n            completion(done)\n            \n        }\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UILabel+IBInspectable.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UILabel+IBInspectable.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic extension UILabel {\n    \n    @IBInspectable\n    var lastLineFillPercent: Int {\n        get { return lastLineFillingPercent }\n        set { lastLineFillingPercent = min(newValue, 100) }\n    }\n    \n    @IBInspectable\n    var linesCornerRadius: Int {\n        get { return multilineCornerRadius }\n        set { multilineCornerRadius = newValue }\n    }\n    \n    @IBInspectable\n    var skeletonLineSpacing: CGFloat {\n        get { return multilineSpacing }\n        set { multilineSpacing = newValue }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UILabel+SKExtensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UILabel+SKExtensions.swift\n//\n//  Created by Juanpe Catalán on 23/8/21.\n\nimport UIKit\n\npublic extension UILabel {\n    \n    /// Defines the skeleton paddings.\n    var skeletonPaddingInsets: UIEdgeInsets {\n        get {\n            paddingInsets\n        }\n        set {\n            paddingInsets = newValue\n        }\n    }\n    \n    /// Defines the logic for calculating the height of the skeleton lines.\n    /// Default: `SkeletonAppearance.default.textLineHeight`\n    var skeletonTextLineHeight: SkeletonTextLineHeight {\n        get {\n            textLineHeight\n        }\n        set {\n            textLineHeight = newValue\n        }\n    }\n    \n    /// Defines the logic for calculating the number of lines of the skeleton.\n    /// Default: `inherited`\n    var skeletonTextNumberOfLines: SkeletonTextNumberOfLines {\n        get {\n            skeletonNumberOfLines\n        }\n        set {\n            skeletonNumberOfLines = newValue\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UITextView+IBInspectable.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UITextView+IBInspectable.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic extension UITextView {\n    \n    @IBInspectable\n    var lastLineFillPercent: Int {\n        get { return lastLineFillingPercent }\n        set { lastLineFillingPercent = min(newValue, 100) }\n    }\n\n    @IBInspectable\n    var linesCornerRadius: Int {\n        get { return multilineCornerRadius }\n        set { multilineCornerRadius = newValue }\n    }\n\n    @IBInspectable\n    var skeletonLineSpacing: CGFloat {\n        get { return multilineSpacing }\n        set { multilineSpacing = newValue }\n    }\n\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UITextView+SKExtensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UITextView+SKExtensions.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\npublic extension UITextView {\n\n    /// Defines the skeleton paddings.\n    var skeletonPaddingInsets: UIEdgeInsets {\n        get {\n            paddingInsets\n        }\n        set {\n            paddingInsets = newValue\n        }\n    }\n    \n    /// Defines the logic for calculating the height of the skeleton lines.\n    /// Default: `SkeletonAppearance.default.textLineHeight`\n    var skeletonTextLineHeight: SkeletonTextLineHeight {\n        get {\n            textLineHeight\n        }\n        set {\n            textLineHeight = newValue\n        }\n    }\n    \n    /// Defines the logic for calculating the number of lines of the skeleton.\n    /// Default: `inherited`\n    var skeletonTextNumberOfLines: SkeletonTextNumberOfLines {\n        get {\n            skeletonNumberOfLines\n        }\n        set {\n            skeletonNumberOfLines = newValue\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UIView+IBInspectable.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+IBInspectable.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\npublic extension UIView {\n    \n    @IBInspectable\n    var isSkeletonable: Bool {\n        get { _skeletonable }\n        set { _skeletonable = newValue }\n    }\n    \n    @IBInspectable\n    var isHiddenWhenSkeletonIsActive: Bool {\n        get { _hiddenWhenSkeletonIsActive }\n        set { _hiddenWhenSkeletonIsActive = newValue }\n    }\n    \n    @IBInspectable\n    var isUserInteractionDisabledWhenSkeletonIsActive: Bool {\n        get { _disabledWhenSkeletonIsActive }\n        set { _disabledWhenSkeletonIsActive = newValue }\n    }\n\n    @IBInspectable\n    var skeletonCornerRadius: Float {\n        get { _skeletonableCornerRadius }\n        set { _skeletonableCornerRadius = newValue }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/API/UIKitExtensions/UIView+SKExtensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+SKExtensions.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\npublic extension SkeletonViewExtension where ExtendedType: UIView {\n    \n    /// Returns a string that describes the hierarchy of the skeleton, indicating\n    /// whether the receiver is skeletonable and all skeletonable children.\n    var skeletonTreeDescription: String {\n        guard let theJSONData = try? JSONSerialization.data(withJSONObject: treeNode.dictionaryRepresentation, options: [.prettyPrinted]) else {\n            skeletonLog(\"Skeleton tree generation has failed!\")\n            return \"\"\n        }\n        \n        return String(data: theJSONData, encoding: .utf8)!\n    }\n    \n    var isSkeletonActive: Bool {\n        type._status == .on || type.subviewsSkeletonables.contains(where: { $0.sk.isSkeletonActive })\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Collections/CollectionSkeleton.swift",
    "content": "//\n//  CollectionSkeleton.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nenum CollectionAssociatedKeys {\n    static var dummyDataSource = \"dummyDataSource\"\n    static var dummyDelegate = \"dummyDelegate\"\n}\n\nprotocol CollectionSkeleton {\n    \n    var skeletonDataSource: SkeletonCollectionDataSource? { get set }\n    var skeletonDelegate: SkeletonCollectionDelegate? { get set }\n    var estimatedNumberOfRows: Int { get }\n    \n    func addDummyDataSource()\n    func updateDummyDataSource()\n    func removeDummyDataSource(reloadAfter: Bool)\n    func disableUserInteraction()\n    func enableUserInteraction()\n    \n}\n\nextension CollectionSkeleton where Self: UIScrollView {\n    \n    var estimatedNumberOfRows: Int { return 0 }\n    func addDummyDataSource() {}\n    func removeDummyDataSource(reloadAfter: Bool) {}\n\n    func disableUserInteraction() {\n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n            isScrollEnabled = false\n        }\n    }\n    \n    func enableUserInteraction() {\n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = true\n            isScrollEnabled = true\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDataSource.swift",
    "content": "//\n//  SkeletonCollectionDataSource.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\npublic typealias ReusableCellIdentifier = String\n\nclass SkeletonCollectionDataSource: NSObject {\n    weak var originalTableViewDataSource: SkeletonTableViewDataSource?\n    weak var originalCollectionViewDataSource: SkeletonCollectionViewDataSource?\n    var rowHeight: CGFloat = 0.0\n    var originalRowHeight: CGFloat = 0.0\n    \n    convenience init(tableViewDataSource: SkeletonTableViewDataSource? = nil, collectionViewDataSource: SkeletonCollectionViewDataSource? = nil, rowHeight: CGFloat = 0.0, originalRowHeight: CGFloat = 0.0) {\n        self.init()\n        self.originalTableViewDataSource = tableViewDataSource\n        self.originalCollectionViewDataSource = collectionViewDataSource\n        self.rowHeight = rowHeight\n        self.originalRowHeight = originalRowHeight\n    }\n}\n\n// MARK: - UITableViewDataSource\nextension SkeletonCollectionDataSource: UITableViewDataSource {\n    func numberOfSections(in tableView: UITableView) -> Int {\n        originalTableViewDataSource?.numSections(in: tableView) ?? 0\n    }\n    \n    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n        guard let originalTableViewDataSource = originalTableViewDataSource else {\n            return 0\n        }\n\n        let numberOfRows = originalTableViewDataSource.collectionSkeletonView(tableView, numberOfRowsInSection: section)\n\n        if numberOfRows == UITableView.automaticNumberOfSkeletonRows {\n            return tableView.estimatedNumberOfRows\n        } else {\n            return numberOfRows\n        }\n    }\n    \n    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n        guard let cell = originalTableViewDataSource?.collectionSkeletonView(tableView, skeletonCellForRowAt: indexPath) else {\n            let cellIdentifier = originalTableViewDataSource?.collectionSkeletonView(tableView, cellIdentifierForRowAt: indexPath) ?? \"\"\n            let fakeCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)\n\n            originalTableViewDataSource?.collectionSkeletonView(tableView, prepareCellForSkeleton: fakeCell, at: indexPath)\n            skeletonizeViewIfContainerSkeletonIsActive(container: tableView, view: fakeCell)\n            \n            return fakeCell\n        }\n\n        originalTableViewDataSource?.collectionSkeletonView(tableView, prepareCellForSkeleton: cell, at: indexPath)\n        skeletonizeViewIfContainerSkeletonIsActive(container: tableView, view: cell)\n        return cell\n    }\n}\n\n// MARK: - UICollectionViewDataSource\nextension SkeletonCollectionDataSource: UICollectionViewDataSource {\n    func numberOfSections(in collectionView: UICollectionView) -> Int {\n        originalCollectionViewDataSource?.numSections(in: collectionView) ?? 0\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {\n        guard let originalCollectionViewDataSource = originalCollectionViewDataSource else {\n            return 0\n        }\n\n        let numberOfItems = originalCollectionViewDataSource.collectionSkeletonView(collectionView, numberOfItemsInSection: section)\n\n        if numberOfItems == UICollectionView.automaticNumberOfSkeletonItems {\n            return collectionView.estimatedNumberOfRows\n        } else {\n            return numberOfItems\n        }\n    }\n    \n    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {\n        guard let cell = originalCollectionViewDataSource?.collectionSkeletonView(collectionView, skeletonCellForItemAt: indexPath) else {\n            let cellIdentifier = originalCollectionViewDataSource?.collectionSkeletonView(collectionView, cellIdentifierForItemAt: indexPath) ?? \"\"\n            let fakeCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)\n\n            originalCollectionViewDataSource?.collectionSkeletonView(collectionView, prepareCellForSkeleton: fakeCell, at: indexPath)\n            skeletonizeViewIfContainerSkeletonIsActive(container: collectionView, view: fakeCell)\n            \n            return fakeCell\n        }\n\n        originalCollectionViewDataSource?.collectionSkeletonView(collectionView, prepareCellForSkeleton: cell, at: indexPath)\n        skeletonizeViewIfContainerSkeletonIsActive(container: collectionView, view: cell)\n        return cell\n    }\n    \n    func collectionView(_ collectionView: UICollectionView,\n                        viewForSupplementaryElementOfKind kind: String,\n                        at indexPath: IndexPath) -> UICollectionReusableView {\n        if let viewIdentifier = originalCollectionViewDataSource?.collectionSkeletonView(collectionView, supplementaryViewIdentifierOfKind: kind, at: indexPath) {\n            let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: viewIdentifier, for: indexPath)\n\n            originalCollectionViewDataSource?.collectionSkeletonView(collectionView, prepareViewForSkeleton: view, at: indexPath)\n            skeletonizeViewIfContainerSkeletonIsActive(container: collectionView, view: view)\n            return view\n        }\n        \n        return originalCollectionViewDataSource?.collectionView?(collectionView, viewForSupplementaryElementOfKind: kind, at: indexPath) ?? UICollectionReusableView()\n    }\n    \n}\n\nextension SkeletonCollectionDataSource {\n    private func skeletonizeViewIfContainerSkeletonIsActive(container: UIView, view: UIView) {\n        guard container.sk.isSkeletonActive,\n              let skeletonConfig = container._currentSkeletonConfig else {\n            return\n        }\n\n        view.showSkeleton(\n            skeletonConfig: skeletonConfig,\n            notifyDelegate: false\n        )\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Collections/SkeletonCollectionDelegate.swift",
    "content": "//\n//  SkeletonCollectionDelegate.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 30/03/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nclass SkeletonCollectionDelegate: NSObject {\n    \n    weak var originalTableViewDelegate: SkeletonTableViewDelegate?\n    weak var originalCollectionViewDelegate: SkeletonCollectionViewDelegate?\n    \n    init(\n        tableViewDelegate: SkeletonTableViewDelegate? = nil,\n        collectionViewDelegate: SkeletonCollectionViewDelegate? = nil\n    ) {\n        self.originalTableViewDelegate = tableViewDelegate\n        self.originalCollectionViewDelegate = collectionViewDelegate\n    }\n    \n}\n\n// MARK: - UITableViewDelegate\nextension SkeletonCollectionDelegate: UITableViewDelegate {\n    \n    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {\n        headerOrFooterView(tableView, for: originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForHeaderInSection: section))\n    }\n\n    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {\n        headerOrFooterView(tableView, for: originalTableViewDelegate?.collectionSkeletonView(tableView, identifierForFooterInSection: section))\n    }\n\n    func tableView(_ tableView: UITableView, didEndDisplayingHeaderView view: UIView, forSection section: Int) {\n        view.hideSkeleton()\n        originalTableViewDelegate?.tableView?(tableView, didEndDisplayingHeaderView: view, forSection: section)\n    }\n    \n    func tableView(_ tableView: UITableView, didEndDisplayingFooterView view: UIView, forSection section: Int) {\n        view.hideSkeleton()\n        originalTableViewDelegate?.tableView?(tableView, didEndDisplayingFooterView: view, forSection: section)\n    }\n    \n    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {\n        cell.hideSkeleton()\n        originalTableViewDelegate?.tableView?(tableView, didEndDisplaying: cell, forRowAt: indexPath)\n    }\n    \n}\n\n// MARK: - UICollectionViewDelegate\nextension SkeletonCollectionDelegate: UICollectionViewDelegate { }\n\nprivate extension SkeletonCollectionDelegate {\n    \n    func skeletonizeViewIfContainerSkeletonIsActive(container: UIView, view: UIView) {\n        guard container.sk.isSkeletonActive,\n              let skeletonConfig = container._currentSkeletonConfig\n        else {\n            return\n        }\n\n        view.showSkeleton(\n            skeletonConfig: skeletonConfig,\n            notifyDelegate: false\n        )\n    }\n    \n    func headerOrFooterView(_ tableView: UITableView, for viewIdentifier: String? ) -> UIView? {\n        guard let viewIdentifier = viewIdentifier,\n              let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: viewIdentifier)\n        else {\n            return nil\n        }\n        \n        skeletonizeViewIfContainerSkeletonIsActive(\n            container: tableView,\n            view: header\n        )\n        \n        return header\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Collections/SkeletonReusableCell.swift",
    "content": "//\n//  SkeletonReusableCell.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 30/03/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\npublic protocol SkeletonReusableCell { }\n\nextension UITableViewCell: SkeletonReusableCell { }\n\nextension UICollectionViewCell: SkeletonReusableCell { }\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Debug/SkeletonDebug.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonDebug.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport Foundation\nimport UIKit\n\nenum SkeletonEnvironmentKey: String {\n    case debugMode = \"SKELETON_DEBUG\"\n}\n\nextension Dictionary {\n    subscript (_ key: SkeletonEnvironmentKey) -> Value? {\n        // swiftlint:disable:next force_cast\n        return self[key.rawValue as! Key]\n    }\n}\n\nfunc skeletonLog(_ message: String) {\n    #if DEBUG\n    if ProcessInfo.processInfo.environment[.debugMode] != nil {\n        print(message)\n    }\n    #endif\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/FoundationExtensions/DispatchQueue+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  DispatchQueue+Extensions.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport Foundation\n\nextension DispatchQueue {\n    \n    private static var _onceTracker = [String]()\n\n    class func once(token: String, block: () -> Void) {\n        objc_sync_enter(self)\n        defer { objc_sync_exit(self) }\n        guard !_onceTracker.contains(token) else { return }\n\n        _onceTracker.append(token)\n        block()\n    }\n\n    class func removeOnce(token: String, block: () -> Void) {\n        objc_sync_enter(self)\n        defer { objc_sync_exit(self) }\n        guard let index = _onceTracker.firstIndex(of: token) else { return }\n        _onceTracker.remove(at: index)\n        block()\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/FoundationExtensions/Int+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  Int+Extensions.swift\n//\n\nimport Foundation\n\nextension Int {\n    \n    var whitespace: String {\n        whitespaces\n    }\n    \n    var whitespaces: String {\n        String(repeating: \" \", count: self)\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/FoundationExtensions/Notification+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  Notification+Extensions.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\nextension Notification.Name {\n    \n    static let applicationDidBecomeActiveNotification = UIApplication.didBecomeActiveNotification\n    static let applicationWillTerminateNotification = UIApplication.willTerminateNotification\n    static let applicationDidEnterForegroundNotification = UIApplication.didEnterBackgroundNotification\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/FoundationExtensions/ProcessInfo+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  ProcessInfo+Extensions.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport Foundation\n\nextension ProcessInfo {\n    \n    enum Constants {\n        static let testConfigurationFilePathKey = \"XCTestConfigurationFilePath\"\n    }\n    \n    static var isRunningXCTest: Bool {\n        return processInfo.environment[Constants.testConfigurationFilePathKey] != nil\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Helpers/AssociationPolicy.swift",
    "content": "//  Copyright © 2017 SkeletonView. All rights reserved.\n\nimport Foundation\n\n// Partially copy/pasted from https://github.com/jameslintaylor/AssociatedObjects/blob/master/AssociatedObjects/AssociatedObjects.swift\nenum AssociationPolicy: UInt {\n    // raw values map to objc_AssociationPolicy's raw values\n    case assign = 0\n    case copy = 771\n    case copyNonatomic = 3\n    case retain = 769\n    case retainNonatomic = 1\n    \n    var objc: objc_AssociationPolicy {\n        // swiftlint:disable:next force_unwrapping\n        return objc_AssociationPolicy(rawValue: rawValue)!\n    }\n}\n\nprotocol AssociatedObjects: AnyObject { }\n\nextension AssociatedObjects {\n    /// wrapper around `objc_getAssociatedObject`\n    func ao_get(pkey: UnsafeRawPointer) -> Any? {\n        return objc_getAssociatedObject(self, pkey)\n    }\n\n    /// wrapper around `objc_setAssociatedObject`\n    func ao_setOptional(_ value: Any?, pkey: UnsafeRawPointer, policy: AssociationPolicy = .retainNonatomic) {\n        guard let value = value else { return }\n        objc_setAssociatedObject(self, pkey, value, policy.objc)\n    }\n\n    /// wrapper around `objc_setAssociatedObject`\n    func ao_set(_ value: Any, pkey: UnsafeRawPointer, policy: AssociationPolicy = .retainNonatomic) {\n        objc_setAssociatedObject(self, pkey, value, policy.objc)\n    }\n\n    /// wrapper around 'objc_removeAssociatedObjects'\n    func ao_removeAll() {\n        objc_removeAssociatedObjects(self)\n    }\n}\n\nextension NSObject: AssociatedObjects { }\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Helpers/Recursive.swift",
    "content": "//  Copyright © 2017 SkeletonView. All rights reserved.\n\nimport UIKit\n\ntypealias VoidBlock = () -> Void\ntypealias RecursiveBlock<T> = (T) -> Void\n\nprotocol IterableElement {}\nextension UIView: IterableElement {}\nextension CALayer: IterableElement {}\n\n// MARK: Recursive\nprotocol Recursive {\n    associatedtype Element: IterableElement\n    func recursiveSearch(leafBlock: VoidBlock, recursiveBlock: RecursiveBlock<Element>)\n}\n\nextension Array: Recursive where Element: IterableElement {\n    func recursiveSearch(leafBlock: VoidBlock, recursiveBlock: RecursiveBlock<Element>) {\n        guard !isEmpty else {\n            leafBlock()\n            return\n        }\n        forEach { recursiveBlock($0) }\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Helpers/Swizzling.swift",
    "content": "// Copyright © 2019 SkeletonView. All rights reserved.\n\nimport Foundation\n\nfunc swizzle(selector originalSelector: Selector, with swizzledSelector: Selector, inClass: AnyClass, usingClass: AnyClass) {\n    guard let originalMethod = class_getInstanceMethod(inClass, originalSelector),\n        let swizzledMethod = class_getInstanceMethod(usingClass, swizzledSelector)\n        else { return }\n\n    if class_addMethod(inClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)) {\n        class_replaceMethod(inClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))\n    } else {\n        method_exchangeImplementations(originalMethod, swizzledMethod)\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Models/RecoverableViewState.swift",
    "content": "//\n//  RecoverableViewState.swift\n//  SkeletonView\n//\n//  Created by Juanpe Catalán on 13/05/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nstruct RecoverableViewState {\n    \n    var backgroundColor: UIColor?\n    var cornerRadius: CGFloat\n    var clipToBounds: Bool\n    var isUserInteractionsEnabled: Bool\n    \n    init(view: UIView) {\n        self.backgroundColor = view.backgroundColor\n        self.clipToBounds = view.layer.masksToBounds\n        self.cornerRadius = view.layer.cornerRadius\n        self.isUserInteractionsEnabled = view.isUserInteractionEnabled\n    }\n    \n}\n\nstruct RecoverableLabelState {\n    var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined\n    var text: String? // we mess with `text` if the label is within a `UIStackView`\n    var textColor: UIColor?\n\n    init(view: UILabel) {\n        if let attributedText = view.attributedText {\n            self.attributedText = attributedText\n        } else {\n            self.text = view.text\n        }\n        self.textColor = view.textColor\n    }\n}\n\nstruct RecoverableTextViewState {\n    var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined\n    var textColor: UIColor?\n    \n    init(view: UITextView) {\n        self.attributedText = view.attributedText\n        self.textColor = view.textColor\n    }\n}\n\nstruct RecoverableTextFieldState {\n    var attributedText: NSAttributedString? // we mess with `textColor`, which impacts attributed string if defined\n    var textColor: UIColor?\n    var placeholder: String?\n\n    init(view: UITextField) {\n        self.attributedText = view.attributedText\n        self.textColor = view.textColor\n        self.placeholder = view.placeholder\n    }\n}\n\nstruct RecoverableImageViewState {\n    var image: UIImage?\n    \n    init(view: UIImageView) {\n        self.image = view.image\n    }\n}\n\nstruct RecoverableButtonViewState {\n    var title: String?\n    \n    init(view: UIButton) {\n        self.title = view.titleLabel?.text\n    }\n}\n\nstruct RecoverableTableViewHeaderFooterViewState {\n    var backgroundViewColor: UIColor?\n    \n    init(view: UITableViewHeaderFooterView) {\n        self.backgroundViewColor = view.backgroundView?.backgroundColor\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/Models/SkeletonLayer.swift",
    "content": "//\n//  SkeletonLayer.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/11/2017.\n//  Copyright © 2017 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nstruct SkeletonLayer {\n    \n    private var maskLayer: CALayer\n    private weak var holder: UIView?\n    \n    var type: SkeletonType {\n        return maskLayer is CAGradientLayer ? .gradient : .solid\n    }\n    \n    var contentLayer: CALayer {\n        return maskLayer\n    }\n    \n    init(type: SkeletonType, colors: [UIColor], skeletonHolder holder: UIView) {\n        self.holder = holder\n        self.maskLayer = type.layer\n        self.maskLayer.anchorPoint = .zero\n        self.maskLayer.bounds = holder.definedMaxBounds\n        self.maskLayer.cornerRadius = CGFloat(holder.skeletonCornerRadius)\n        addTextLinesIfNeeded()\n        self.maskLayer.tint(withColors: colors, traitCollection: holder.traitCollection)\n    }\n    \n    func update(usingColors colors: [UIColor]) {\n        layoutIfNeeded()\n        maskLayer.tint(withColors: colors, traitCollection: holder?.traitCollection)\n    }\n\n    func layoutIfNeeded() {\n        if let bounds = holder?.definedMaxBounds {\n            maskLayer.bounds = bounds\n        }\n        updateLinesIfNeeded()\n    }\n    \n    func removeLayer(transition: SkeletonTransitionStyle, completion: (() -> Void)? = nil) {\n        switch transition {\n        case .none:\n            maskLayer.removeFromSuperlayer()\n            completion?()\n        case .crossDissolve(let duration):\n            maskLayer.setOpacity(from: 1, to: 0, duration: duration) {\n                self.maskLayer.removeFromSuperlayer()\n                completion?()\n            }\n        }\n    }\n\n    /// If there is more than one line, or custom preferences have been set for a single line, draw custom layers\n    func addTextLinesIfNeeded() {\n        guard let textView = holderAsTextView else { return }\n        let config = SkeletonMultilinesLayerConfig(lines: textView.estimatedNumberOfLines,\n                                                   lineHeight: textView.estimatedLineHeight,\n                                                   type: type,\n                                                   lastLineFillPercent: textView.lastLineFillingPercent,\n                                                   multilineCornerRadius: textView.multilineCornerRadius,\n                                                   multilineSpacing: textView.multilineSpacing,\n                                                   paddingInsets: textView.paddingInsets,\n                                                   alignment: textView.textAlignment,\n                                                   isRTL: holder?.isRTL ?? false,\n                                                   shouldCenterVertically: textView.shouldCenterTextVertically)\n\n        maskLayer.addMultilinesLayers(for: config)\n    }\n    \n    func updateLinesIfNeeded() {\n        guard let textView = holderAsTextView else { return }\n        let config = SkeletonMultilinesLayerConfig(lines: textView.estimatedNumberOfLines,\n                                                   lineHeight: textView.estimatedLineHeight,\n                                                   type: type,\n                                                   lastLineFillPercent: textView.lastLineFillingPercent,\n                                                   multilineCornerRadius: textView.multilineCornerRadius,\n                                                   multilineSpacing: textView.multilineSpacing,\n                                                   paddingInsets: textView.paddingInsets,\n                                                   alignment: textView.textAlignment,\n                                                   isRTL: holder?.isRTL ?? false,\n                                                   shouldCenterVertically: textView.shouldCenterTextVertically)\n        \n        maskLayer.updateMultilinesLayers(for: config)\n    }\n    \n    var holderAsTextView: SkeletonTextNode? {\n        guard let textView = holder as? SkeletonTextNode,\n            (textView.estimatedNumberOfLines == -1 || textView.estimatedNumberOfLines == 0 || textView.estimatedNumberOfLines > 1 || textView.estimatedNumberOfLines == 1 && !SkeletonAppearance.default.renderSingleLineAsView) else {\n                return nil\n        }\n        return textView\n    }\n    \n}\n\nextension SkeletonLayer {\n    \n    func start(_ anim: SkeletonLayerAnimation? = nil, completion: (() -> Void)? = nil) {\n        let animation = anim ?? type.defaultLayerAnimation(isRTL: holder?.isRTL ?? false)\n        contentLayer.playAnimation(animation, key: \"skeletonAnimation\", completion: completion)\n    }\n\n    func stopAnimation() {\n        contentLayer.stopAnimation(forKey: \"skeletonAnimation\")\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonConfig.swift",
    "content": "// Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\n/// Used to store all config needed to activate the skeleton layer.\nstruct SkeletonConfig {\n    /// Type of skeleton layer\n    let type: SkeletonType\n    \n    /// Colors used in skeleton layer\n    let colors: [UIColor]\n    \n    /// If type is gradient, which gradient direction\n    let gradientDirection: GradientDirection?\n    \n    /// Specify if skeleton is animated or not\n    let animated: Bool\n    \n    /// Used to execute a custom animation\n    let animation: SkeletonLayerAnimation?\n    \n    ///  Transition style\n    var transition: SkeletonTransitionStyle\n    \n    init(type: SkeletonType,\n         colors: [UIColor],\n         gradientDirection: GradientDirection? = nil,\n         animated: Bool = false,\n         animation: SkeletonLayerAnimation? = nil,\n         transition: SkeletonTransitionStyle = .crossDissolve(0.25)) {\n        self.type = type\n        self.colors = colors\n        self.gradientDirection = gradientDirection\n        self.animated = animated\n        self.animation = animation\n        self.transition = transition\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonConfigs/SkeletonMultilinesLayerConfig.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonMultilinesLayerConfig.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\nstruct SkeletonMultilinesLayerConfig {\n    \n    var lines: Int\n    var lineHeight: CGFloat\n    var type: SkeletonType\n    var lastLineFillPercent: Int\n    var multilineCornerRadius: Int\n    var multilineSpacing: CGFloat\n    var paddingInsets: UIEdgeInsets\n    var alignment: NSTextAlignment\n    var isRTL: Bool\n    var shouldCenterVertically: Bool\n\n    /// Returns padding insets taking into account if the RTL is activated\n    var calculatedPaddingInsets: UIEdgeInsets {\n        UIEdgeInsets(top: paddingInsets.top,\n                     left: isRTL ? paddingInsets.right : paddingInsets.left,\n                     bottom: paddingInsets.bottom,\n                     right: isRTL ? paddingInsets.left : paddingInsets.right)\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonExtensions/GradientDirection+Animations.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  GradientDirection+Animations.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\ntypealias GradientAnimationPoint = (from: CGPoint, to: CGPoint)\n\nextension GradientDirection {\n    \n    // codebeat:disable[ABC]\n    var startPoint: GradientAnimationPoint {\n        switch self {\n        case .leftRight:\n            return (from: CGPoint(x: -1, y: 0.5), to: CGPoint(x: 1, y: 0.5))\n        case .rightLeft:\n            return (from: CGPoint(x: 1, y: 0.5), to: CGPoint(x: -1, y: 0.5))\n        case .topBottom:\n            return (from: CGPoint(x: 0.5, y: -1), to: CGPoint(x: 0.5, y: 1))\n        case .bottomTop:\n            return (from: CGPoint(x: 0.5, y: 1), to: CGPoint(x: 0.5, y: -1))\n        case .topLeftBottomRight:\n            return (from: CGPoint(x: -1, y: -1), to: CGPoint(x: 1, y: 1))\n        case .bottomRightTopLeft:\n            return (from: CGPoint(x: 1, y: 1), to: CGPoint(x: -1, y: -1))\n        }\n    }\n    \n    var endPoint: GradientAnimationPoint {\n        switch self {\n        case .leftRight:\n            return (from: CGPoint(x: 0, y: 0.5), to: CGPoint(x: 2, y: 0.5))\n        case .rightLeft:\n            return ( from: CGPoint(x: 2, y: 0.5), to: CGPoint(x: 0, y: 0.5))\n        case .topBottom:\n            return ( from: CGPoint(x: 0.5, y: 0), to: CGPoint(x: 0.5, y: 2))\n        case .bottomTop:\n            return ( from: CGPoint(x: 0.5, y: 2), to: CGPoint(x: 0.5, y: 0))\n        case .topLeftBottomRight:\n            return ( from: CGPoint(x: 0, y: 0), to: CGPoint(x: 2, y: 2))\n        case .bottomRightTopLeft:\n            return ( from: CGPoint(x: 2, y: 2), to: CGPoint(x: 0, y: 0))\n        }\n    }\n    // codebeat:enable[ABC]\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonExtensions/PrepareViewForSkeleton.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  PrepareViewForSkeleton.swift\n//\n//  Created by Juanpe Catalán on 04/11/2017.\n\nimport UIKit\n\nextension UIView {\n    \n    @objc func prepareViewForSkeleton() {\n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n        \n        startTransition { [weak self] in\n            self?.backgroundColor = .clear\n        }\n    }\n    \n}\n\nextension UILabel {\n    \n    override func prepareViewForSkeleton() {\n        backgroundColor = .clear\n        \n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n        \n        resignFirstResponder()\n        startTransition { [weak self] in\n            self?.updateHeightConstraintsIfNeeded()\n            self?.textColor = .clear\n        }\n    }\n}\n\nextension UITextView {\n    \n    override func prepareViewForSkeleton() {\n        backgroundColor = .clear\n        \n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n        \n        resignFirstResponder()\n        startTransition { [weak self] in\n            self?.textColor = .clear\n        }\n    }\n    \n}\n\nextension UITextField {\n    \n    override func prepareViewForSkeleton() {\n        backgroundColor = .clear\n        resignFirstResponder()\n\n        startTransition { [weak self] in\n            self?.textColor = .clear\n            self?.placeholder = nil\n        }\n    }\n    \n}\n\nextension UIImageView {\n    \n    override func prepareViewForSkeleton() {\n        backgroundColor = .clear\n        \n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n        \n        startTransition { [weak self] in\n            self?.image = nil\n        }\n    }\n    \n}\n\nextension UIButton {\n    \n    override func prepareViewForSkeleton() {\n        backgroundColor = .clear\n        \n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n        \n        startTransition { [weak self] in\n            self?.setTitle(nil, for: .normal)\n        }\n    }\n    \n}\n\nextension UITableViewHeaderFooterView {\n    \n    override func prepareViewForSkeleton() {\n        backgroundView?.backgroundColor = .clear\n        \n        if isUserInteractionDisabledWhenSkeletonIsActive {\n            isUserInteractionEnabled = false\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonExtensions/Recoverable.swift",
    "content": "//\n//  Recoverable.swift\n//  SkeletonView\n//\n//  Created by Juanpe Catalán on 13/05/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nprotocol Recoverable {\n    func saveViewState()\n    func recoverViewState(forced: Bool)\n}\n\nextension UIView: Recoverable {\n    \n    var viewState: RecoverableViewState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.viewState) as? RecoverableViewState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.viewState) }\n    }\n    \n    @objc func saveViewState() {\n        viewState = RecoverableViewState(view: self)\n    }\n    \n    @objc func recoverViewState(forced: Bool) {\n        guard let storedViewState = viewState else { return }\n        \n        startTransition { [weak self] in\n            guard let self = self else { return }\n            \n            self.layer.cornerRadius = storedViewState.cornerRadius\n            self.layer.masksToBounds = storedViewState.clipToBounds\n            \n            if self.isUserInteractionDisabledWhenSkeletonIsActive {\n                self.isUserInteractionEnabled = storedViewState.isUserInteractionsEnabled\n            }\n            \n            if self.backgroundColor == .clear || forced {\n                self.backgroundColor = storedViewState.backgroundColor\n            }\n        }\n    }\n    \n}\n\nextension UILabel {\n    \n    var labelState: RecoverableLabelState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableLabelState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }\n    }\n    \n    override func saveViewState() {\n        super.saveViewState()\n        labelState = RecoverableLabelState(view: self)\n    }\n    \n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            guard let self = self,\n                  let storedLabelState = self.labelState else {\n                return\n            }\n            \n            NSLayoutConstraint.deactivate(self.skeletonHeightConstraints)\n            self.restoreBackupHeightConstraintsIfNeeded()\n            \n            if self.textColor == .clear || forced {\n                self.textColor = storedLabelState.textColor\n                if let attributedText = storedLabelState.attributedText {\n                    self.attributedText = attributedText\n                } else {\n                    self.text = storedLabelState.text\n                }\n            }\n        }\n    }\n    \n}\n\nextension UITextView {\n    \n    var textState: RecoverableTextViewState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextViewState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }\n    }\n    \n    override func saveViewState() {\n        super.saveViewState()\n        textState = RecoverableTextViewState(view: self)\n    }\n    \n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            guard let storedLabelState = self?.textState else { return }\n            \n            if self?.textColor == .clear || forced {\n                self?.textColor = storedLabelState.textColor\n                if let attributedText = storedLabelState.attributedText {\n                    self?.attributedText = attributedText\n                }\n            }\n        }\n    }\n    \n}\n\nextension UITextField {\n    \n    var textState: RecoverableTextFieldState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.labelViewState) as? RecoverableTextFieldState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.labelViewState) }\n    }\n\n    override func saveViewState() {\n        super.saveViewState()\n        textState = RecoverableTextFieldState(view: self)\n    }\n\n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            guard let storedLabelState = self?.textState else { return }\n\n            if self?.textColor == .clear || forced {\n                self?.textColor = storedLabelState.textColor\n                if let attributedText = storedLabelState.attributedText {\n                    self?.attributedText = attributedText\n                }\n            }\n\n            if self?.placeholder == nil || forced {\n                self?.placeholder = storedLabelState.placeholder\n            }\n        }\n    }\n    \n}\n\nextension UIImageView {\n    \n    var imageState: RecoverableImageViewState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.imageViewState) as? RecoverableImageViewState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.imageViewState) }\n    }\n    \n    override func saveViewState() {\n        super.saveViewState()\n        imageState = RecoverableImageViewState(view: self)\n    }\n    \n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            self?.image = self?.image == nil || forced ? self?.imageState?.image : self?.image\n        }\n    }\n    \n}\n\nextension UIButton {\n    \n    var buttonState: RecoverableButtonViewState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.buttonViewState) as? RecoverableButtonViewState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.buttonViewState) }\n    }\n    \n    override func saveViewState() {\n        super.saveViewState()\n        buttonState = RecoverableButtonViewState(view: self)\n    }\n    \n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            if self?.title(for: .normal) == nil {\n                self?.setTitle(self?.buttonState?.title, for: .normal)\n            }\n        }\n    }\n    \n}\n\nextension UITableViewHeaderFooterView {\n    \n    var headerFooterState: RecoverableTableViewHeaderFooterViewState? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.headerFooterViewState) as? RecoverableTableViewHeaderFooterViewState }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.headerFooterViewState) }\n    }\n    \n    override func saveViewState() {\n        super.saveViewState()\n        headerFooterState = RecoverableTableViewHeaderFooterViewState(view: self)\n    }\n    \n    override func recoverViewState(forced: Bool) {\n        super.recoverViewState(forced: forced)\n        startTransition { [weak self] in\n            self?.backgroundView?.backgroundColor = self?.headerFooterState?.backgroundViewColor\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonExtensions/SkeletonTextNode.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonTextNode.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\nprotocol SkeletonTextNode {\n    \n    var textLineHeight: SkeletonTextLineHeight { get }\n    var estimatedLineHeight: CGFloat { get }\n    var estimatedNumberOfLines: Int { get }\n    var textAlignment: NSTextAlignment { get }\n    var lastLineFillingPercent: Int { get }\n    var multilineCornerRadius: Int { get }\n    var multilineSpacing: CGFloat { get }\n    var paddingInsets: UIEdgeInsets { get }\n    var shouldCenterTextVertically: Bool { get }\n    \n}\n\nenum SkeletonTextNodeAssociatedKeys {\n    \n    static var lastLineFillingPercent = \"lastLineFillingPercent\"\n    static var multilineCornerRadius = \"multilineCornerRadius\"\n    static var multilineSpacing = \"multilineSpacing\"\n    static var paddingInsets = \"paddingInsets\"\n    static var backupHeightConstraints = \"backupHeightConstraints\"\n    static var textLineHeight = \"textLineHeight\"\n    static var skeletonNumberOfLines = \"skeletonNumberOfLines\"\n    \n}\n\nextension UILabel: SkeletonTextNode {\n    \n    var estimatedLineHeight: CGFloat {\n        switch textLineHeight {\n        case .fixed(let height):\n            return height\n        case .relativeToFont:\n            return fontLineHeight ?? SkeletonAppearance.default.multilineHeight\n        case .relativeToConstraints:\n            guard let constraintsLineHeight = heightConstraints.first?.constant,\n                  estimatedNumberOfLines != 0 else {\n                return SkeletonAppearance.default.multilineHeight\n            }\n            \n            return constraintsLineHeight / CGFloat(estimatedNumberOfLines)\n        }\n    }\n    \n    var textLineHeight: SkeletonTextLineHeight {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.textLineHeight) as? SkeletonTextLineHeight ?? SkeletonAppearance.default.textLineHeight }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.textLineHeight) }\n    }\n    \n    var skeletonNumberOfLines: SkeletonTextNumberOfLines {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.skeletonNumberOfLines) as? SkeletonTextNumberOfLines ?? SkeletonTextNumberOfLines.inherited }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.skeletonNumberOfLines) }\n    }\n    \n    var estimatedNumberOfLines: Int {\n        switch skeletonNumberOfLines {\n        case .inherited:\n            return numberOfLines\n        case .custom(let lines):\n            return lines >= 0 ? lines : 1\n        }\n    }\n    \n    var lastLineFillingPercent: Int {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) as? Int ?? SkeletonAppearance.default.multilineLastLineFillPercent }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) }\n    }\n\n    var multilineCornerRadius: Int {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) as? Int ?? SkeletonAppearance.default.multilineCornerRadius }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) }\n    }\n\n    var multilineSpacing: CGFloat {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) }\n    }\n\n    var paddingInsets: UIEdgeInsets {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) }\n    }\n    \n    var backupHeightConstraints: [NSLayoutConstraint] {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.backupHeightConstraints) as? [NSLayoutConstraint] ?? [] }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.backupHeightConstraints) }\n    }\n    \n    var shouldCenterTextVertically: Bool {\n        true\n    }\n    \n    var fontLineHeight: CGFloat? {\n        if let attributedText = attributedText,\n           attributedText.length > 0 {\n            let attributes = attributedText.attributes(at: 0, effectiveRange: nil)\n            let fontAttribute = attributes.first(where: { $0.key == .font })\n            return fontAttribute?.value as? CGFloat ?? font.lineHeight\n        } else {\n            return font.lineHeight\n        }\n    }\n\n}\n\nextension UITextView: SkeletonTextNode {\n    \n    var estimatedLineHeight: CGFloat {\n        switch textLineHeight {\n        case .fixed(let height):\n            return height\n        case .relativeToFont:\n            return fontLineHeight ?? SkeletonAppearance.default.multilineHeight\n        case .relativeToConstraints:\n            return SkeletonAppearance.default.multilineHeight\n        }\n    }\n    \n    var textLineHeight: SkeletonTextLineHeight {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.textLineHeight) as? SkeletonTextLineHeight ?? SkeletonAppearance.default.textLineHeight }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.textLineHeight) }\n    }\n    \n    var skeletonNumberOfLines: SkeletonTextNumberOfLines {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.skeletonNumberOfLines) as? SkeletonTextNumberOfLines ?? SkeletonTextNumberOfLines.inherited }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.skeletonNumberOfLines) }\n    }\n    \n    var estimatedNumberOfLines: Int {\n        switch skeletonNumberOfLines {\n        case .inherited:\n            return -1\n        case .custom(let lines):\n            return lines >= -1 ? lines : 1\n        }\n    }\n    \n    var lastLineFillingPercent: Int {\n        get {\n            let defaultValue = SkeletonAppearance.default.multilineLastLineFillPercent\n            return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) as? Int ?? defaultValue\n        }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.lastLineFillingPercent) }\n    }\n\n    var multilineCornerRadius: Int {\n        get {\n            let defaultValue = SkeletonAppearance.default.multilineCornerRadius\n            return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) as? Int ?? defaultValue\n        }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineCornerRadius) }\n    }\n\n    var multilineSpacing: CGFloat {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) as? CGFloat ?? SkeletonAppearance.default.multilineSpacing }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.multilineSpacing) }\n    }\n\n    var paddingInsets: UIEdgeInsets {\n        get { return ao_get(pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) as? UIEdgeInsets ?? .zero }\n        set { ao_set(newValue, pkey: &SkeletonTextNodeAssociatedKeys.paddingInsets) }\n    }\n    \n    var shouldCenterTextVertically: Bool {\n        false\n    }\n    \n    var fontLineHeight: CGFloat? {\n        if let attributedText = attributedText,\n           attributedText.length > 0 {\n            let attributes = attributedText.attributes(at: 0, effectiveRange: nil)\n            let fontAttribute = attributes.first(where: { $0.key == .font })\n            return fontAttribute?.value as? CGFloat ?? font?.lineHeight\n        } else {\n            return font?.lineHeight\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonExtensions/SubviewsSkeletonables.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\nextension UIView {\n    \n    @objc var subviewsSkeletonables: [UIView] {\n        subviewsToSkeleton.filter { $0.isSkeletonable }\n    }\n\n    @objc var subviewsToSkeleton: [UIView] {\n        subviews\n    }\n    \n}\n\nextension UITableView {\n    \n    override var subviewsToSkeleton: [UIView] {\n\t\t// on `UIViewController'S onViewDidLoad`, the window is still nil.\n\t\t// Some developer trying to call `view.showAnimatedSkeleton()`\n\t\t// when the request or data is loading which sometimes happens before the ViewDidAppear\n\t\tguard window != nil else { return [] }\n        \n        var result = [UIView]()\n\n        for subview in subviews {\n            if String(describing: type(of: subview)) == \"UITableViewWrapperView\" {\n                result.append(contentsOf: subview.subviews)\n            } else {\n                result.append(subview)\n            }\n        }\n        \n        return result\n    }\n    \n}\n\nextension UITableViewCell {\n    override var subviewsToSkeleton: [UIView] {\n        contentView.subviews\n    }\n}\n\nextension UITableViewHeaderFooterView {\n    override var subviewsToSkeleton: [UIView] {\n        contentView.subviews\n    }\n}\n\nextension UICollectionView {\n    override var subviewsToSkeleton: [UIView] {\n        subviews\n    }\n}\n\nextension UICollectionViewCell {\n    override var subviewsToSkeleton: [UIView] {\n        contentView.subviews\n    }\n}\n\nextension UIStackView {\n    override var subviewsToSkeleton: [UIView] {\n        arrangedSubviews\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonFlowHandler.swift",
    "content": "//  Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\nprotocol SkeletonFlowDelegate: AnyObject {\n    func willBeginShowingSkeletons(rootView: UIView)\n    func didShowSkeletons(rootView: UIView)\n    func willBeginUpdatingSkeletons(rootView: UIView)\n    func didUpdateSkeletons(rootView: UIView)\n    func willBeginLayingSkeletonsIfNeeded(rootView: UIView)\n    func didLayoutSkeletonsIfNeeded(rootView: UIView)\n    func willBeginHidingSkeletons(rootView: UIView)\n    func didHideSkeletons(rootView: UIView)\n}\n\nclass SkeletonFlowHandler: SkeletonFlowDelegate {\n    func willBeginShowingSkeletons(rootView: UIView) {\n        NotificationCenter.default.post(name: .skeletonWillAppearNotification, object: rootView, userInfo: nil)\n        rootView.startObservingAppLifecycleNotifications()\n    }\n\n    func didShowSkeletons(rootView: UIView) {\n        skeletonLog(rootView.sk.skeletonTreeDescription)\n        NotificationCenter.default.post(name: .skeletonDidAppearNotification, object: rootView, userInfo: nil)\n    }\n\n    func willBeginUpdatingSkeletons(rootView: UIView) {\n        NotificationCenter.default.post(name: .skeletonWillUpdateNotification, object: rootView, userInfo: nil)\n    }\n\n    func didUpdateSkeletons(rootView: UIView) {\n        NotificationCenter.default.post(name: .skeletonDidUpdateNotification, object: rootView, userInfo: nil)\n    }\n\n    func willBeginLayingSkeletonsIfNeeded(rootView: UIView) {\n    }\n\n    func didLayoutSkeletonsIfNeeded(rootView: UIView) {\n    }\n\n    func willBeginHidingSkeletons(rootView: UIView) {\n        NotificationCenter.default.post(name: .skeletonWillDisappearNotification, object: rootView, userInfo: nil)\n        rootView.stopObservingAppLifecycleNotications()\n    }\n\n    func didHideSkeletons(rootView: UIView) {\n        rootView._flowDelegate = nil\n        NotificationCenter.default.post(name: .skeletonDidDisappearNotification, object: rootView, userInfo: nil)\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonLayerBuilder.swift",
    "content": "// Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\n/// Object that facilitates the creation of skeleton layers,\n/// based on the builder pattern\nclass SkeletonLayerBuilder {\n    \n    var skeletonType: SkeletonType?\n    var colors: [UIColor] = []\n    var holder: UIView?\n\n    @discardableResult\n    func setSkeletonType(_ type: SkeletonType) -> SkeletonLayerBuilder {\n        self.skeletonType = type\n        return self\n    }\n\n    @discardableResult\n    func addColor(_ color: UIColor) -> SkeletonLayerBuilder {\n        addColors([color])\n    }\n\n    @discardableResult\n    func addColors(_ colors: [UIColor]) -> SkeletonLayerBuilder {\n        self.colors.append(contentsOf: colors)\n        return self\n    }\n\n    @discardableResult\n    func setHolder(_ holder: UIView) -> SkeletonLayerBuilder {\n        self.holder = holder\n        return self\n\t}\n\t\n    @discardableResult\n\tfunc build() -> SkeletonLayer? {\n\t\tguard let type = skeletonType,\n\t\t\tlet holder = holder\n\t\t\telse { return nil }\n\t\t\n\t\treturn SkeletonLayer(type: type,\n\t\t\t\t\t\t\t colors: colors,\n\t\t\t\t\t\t\t skeletonHolder: holder)\n\t}\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonLayerBuilders/SkeletonMultilineLayerBuilder.swift",
    "content": "// Copyright © 2018 SkeletonView. All rights reserved.\n\nimport UIKit\n\n/// Object that facilitates the creation of skeleton layers for multiline\n/// elements, based on the builder pattern\nclass SkeletonMultilineLayerBuilder {\n    \n    var skeletonType: SkeletonType?\n    var index: Int?\n    var height: CGFloat?\n    var width: CGFloat?\n    var cornerRadius: Int?\n    var multilineSpacing: CGFloat = SkeletonAppearance.default.multilineSpacing\n    var paddingInsets: UIEdgeInsets = .zero\n    var alignment: NSTextAlignment = .natural\n    var isRTL: Bool = false\n\n    @discardableResult\n    func setSkeletonType(_ type: SkeletonType) -> SkeletonMultilineLayerBuilder {\n        self.skeletonType = type\n        return self\n    }\n\n    @discardableResult\n    func setIndex(_ index: Int) -> SkeletonMultilineLayerBuilder {\n        self.index = index\n        return self\n    }\n    \n    @discardableResult\n    func setHeight(_ height: CGFloat) -> SkeletonMultilineLayerBuilder {\n        self.height = height\n        return self\n    }\n    \n    @discardableResult\n    func setWidth(_ width: CGFloat) -> SkeletonMultilineLayerBuilder {\n        self.width = width\n        return self\n    }\n\n    @discardableResult\n    func setCornerRadius(_ radius: Int) -> SkeletonMultilineLayerBuilder {\n        self.cornerRadius = radius\n        return self\n    }\n\n    @discardableResult\n    func setMultilineSpacing(_ spacing: CGFloat) -> SkeletonMultilineLayerBuilder {\n        self.multilineSpacing = spacing\n        return self\n    }\n\n    @discardableResult\n    func setPadding(_ insets: UIEdgeInsets) -> SkeletonMultilineLayerBuilder {\n        self.paddingInsets = insets\n        return self\n    }\n\n    @discardableResult\n    func setAlignment(_ alignment: NSTextAlignment) -> SkeletonMultilineLayerBuilder {\n        self.alignment = alignment\n        return self\n    }\n    \n    @discardableResult\n    func setIsRTL(_ isRTL: Bool) -> SkeletonMultilineLayerBuilder {\n        self.isRTL = isRTL\n        return self\n    }\n\n    func build() -> CALayer? {\n        guard let type = skeletonType,\n              let index = index,\n              let width = width,\n              let height = height,\n              let radius = cornerRadius\n            else { return nil }\n\n        let layer = type.layer\n        layer.anchorPoint = .zero\n        layer.name = CALayer.Constants.skeletonSubLayersName\n        layer.updateLayerFrame(for: index,\n                               totalLines: layer.skeletonSublayers.count,\n                               size: CGSize(width: width, height: height),\n                               multilineSpacing: multilineSpacing,\n                               paddingInsets: paddingInsets,\n                               alignment: alignment,\n                               isRTL: isRTL)\n\n        layer.cornerRadius = CGFloat(radius)\n        layer.masksToBounds = true\n\n        return layer\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/SkeletonTree/SkeletonTreeNode.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonTreeNode.swift\n//\n//  Created by Juanpe Catalán on 23/8/21.\n\nimport UIKit\n\npublic struct SkeletonTreeNode<Base> {\n    /// Base object to extend.\n    let base: Base\n\n    /// Creates extensions with base object.\n    ///\n    /// - parameter base: Base object.\n    init(_ base: Base) {\n        self.base = base\n    }\n\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/CALayer+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  CALayer+Tint.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\nextension CAGradientLayer {\n    \n    override func tint(withColors colors: [UIColor], traitCollection: UITraitCollection?) {\n        skeletonSublayers.recursiveSearch(leafBlock: {\n            if #available(iOS 13.0, tvOS 13, *), let traitCollection = traitCollection {\n                self.colors = colors.map { $0.resolvedColor(with: traitCollection).cgColor }\n            } else {\n                self.colors = colors.map { $0.cgColor }\n            }\n        }) {\n            $0.tint(withColors: colors, traitCollection: traitCollection)\n        }\n    }\n    \n}\n\nextension CALayer {\n    \n    enum Constants {\n        static let skeletonSubLayersName = \"SkeletonSubLayersName\"\n    }\n    \n    var skeletonSublayers: [CALayer] {\n        return sublayers?.filter { $0.name == Constants.skeletonSubLayersName } ?? [CALayer]()\n    }\n    \n    @objc func tint(withColors colors: [UIColor], traitCollection: UITraitCollection?) {\n        skeletonSublayers.recursiveSearch(leafBlock: {\n            if #available(iOS 13.0, tvOS 13, *), let traitCollection = traitCollection {\n                backgroundColor = colors.first?.resolvedColor(with: traitCollection).cgColor\n            } else {\n                backgroundColor = colors.first?.cgColor\n            }\n        }) {\n            $0.tint(withColors: colors, traitCollection: traitCollection)\n        }\n    }\n    \n    func playAnimation(_ anim: SkeletonLayerAnimation, key: String, completion: (() -> Void)? = nil) {\n        skeletonSublayers.recursiveSearch(leafBlock: {\n            DispatchQueue.main.async { CATransaction.begin() }\n            DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }\n            add(anim(self), forKey: key)\n            DispatchQueue.main.async { CATransaction.commit() }\n        }) {\n            $0.playAnimation(anim, key: key, completion: completion)\n        }\n    }\n    \n    func stopAnimation(forKey key: String) {\n        skeletonSublayers.recursiveSearch(leafBlock: {\n            removeAnimation(forKey: key)\n        }) {\n            $0.stopAnimation(forKey: key)\n        }\n    }\n    \n    func setOpacity(from: Int, to: Int, duration: TimeInterval, completion: (() -> Void)?) {\n        DispatchQueue.main.async { CATransaction.begin() }\n        let animation = CABasicAnimation(keyPath: #keyPath(CALayer.opacity))\n        animation.fromValue = from\n        animation.toValue = to\n        animation.duration = duration\n        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)\n        DispatchQueue.main.async { CATransaction.setCompletionBlock(completion) }\n        add(animation, forKey: \"setOpacityAnimation\")\n        DispatchQueue.main.async { CATransaction.commit() }\n    }\n    \n    func insertSkeletonLayer(_ sublayer: SkeletonLayer, atIndex index: UInt32, transition: SkeletonTransitionStyle, completion: (() -> Void)? = nil) {\n        insertSublayer(sublayer.contentLayer, at: index)\n        switch transition {\n        case .none:\n            DispatchQueue.main.async { completion?() }\n        case .crossDissolve(let duration):\n            sublayer.contentLayer.setOpacity(from: 0, to: 1, duration: duration, completion: completion)\n        }\n    }\n    \n}\n\nprivate extension CALayer {\n    \n    func alignLayerFrame(_ rect: CGRect, paddingInsets: UIEdgeInsets, alignment: NSTextAlignment, isRTL: Bool) -> CGRect {\n        var newRect = rect\n        let superlayerWidth = (superlayer?.bounds.width ?? 0)\n\n        switch alignment {\n        case .natural where isRTL,\n             .right:\n            newRect.origin.x = superlayerWidth - rect.width - paddingInsets.right\n        case .center:\n            newRect.origin.x = (superlayerWidth + paddingInsets.left - paddingInsets.right - rect.width) / 2\n        case .natural, .left, .justified:\n            break\n        @unknown default:\n            break\n        }\n\n        return newRect\n    }\n    \n    func calculatedWidthForLine(at index: Int, totalLines: Int, lastLineFillPercent: Int, paddingInsets: UIEdgeInsets) -> CGFloat {\n        var width = bounds.width - paddingInsets.left - paddingInsets.right\n        if index == totalLines - 1 {\n            width = width * CGFloat(lastLineFillPercent) / 100\n        }\n        return width\n    }\n \n    func calculateNumLines(for config: SkeletonMultilinesLayerConfig) -> Int {\n        let definedNumberOfLines = config.lines\n        let requiredSpaceForEachLine = config.lineHeight + config.multilineSpacing\n        let neededLines = round(CGFloat(bounds.height - config.paddingInsets.top - config.paddingInsets.bottom) / CGFloat(requiredSpaceForEachLine))\n        guard neededLines.isNormal else {\n            return 0\n        }\n\n        let calculatedNumberOfLines = Int(neededLines)\n        guard calculatedNumberOfLines > 0 else {\n            return 1\n        }\n        \n        if definedNumberOfLines > 0, definedNumberOfLines <= calculatedNumberOfLines {\n            return definedNumberOfLines\n        }\n        \n        return calculatedNumberOfLines\n    }\n}\n\nextension CALayer {\n    \n    func addMultilinesLayers(for config: SkeletonMultilinesLayerConfig) {\n        let numberOfSublayers = config.lines > 0 ? config.lines : calculateNumLines(for: config)\n        var height = config.lineHeight\n        \n        if numberOfSublayers == 1 && SkeletonAppearance.default.renderSingleLineAsView {\n            height = bounds.height\n        }\n\n        let layerBuilder = SkeletonMultilineLayerBuilder()\n            .setSkeletonType(config.type)\n            .setCornerRadius(config.multilineCornerRadius)\n            .setMultilineSpacing(config.multilineSpacing)\n            .setPadding(config.paddingInsets)\n            .setHeight(height)\n            .setAlignment(config.alignment)\n            .setIsRTL(config.isRTL)\n    \n        (0..<numberOfSublayers).forEach { index in\n            let width = calculatedWidthForLine(at: index, totalLines: numberOfSublayers, lastLineFillPercent: config.lastLineFillPercent, paddingInsets: config.paddingInsets)\n            if let layer = layerBuilder\n                .setIndex(index)\n                .setWidth(width)\n                .build() {\n                addSublayer(layer)\n            }\n        }\n    }\n\n    func updateMultilinesLayers(for config: SkeletonMultilinesLayerConfig) {\n        let currentSkeletonSublayers = skeletonSublayers\n        let numberOfSublayers = currentSkeletonSublayers.count\n        let lastLineFillPercent = config.lastLineFillPercent\n        let paddingInsets = config.calculatedPaddingInsets\n        let multilineSpacing = config.multilineSpacing\n        var height = config.lineHeight\n        \n        if numberOfSublayers == 1 && SkeletonAppearance.default.renderSingleLineAsView {\n            height = bounds.height\n        }\n        \n        for (index, layer) in currentSkeletonSublayers.enumerated() {\n            let width = calculatedWidthForLine(at: index, totalLines: numberOfSublayers, lastLineFillPercent: lastLineFillPercent, paddingInsets: paddingInsets)\n            layer.updateLayerFrame(for: index,\n                                   totalLines: numberOfSublayers,\n                                   size: CGSize(width: width, height: height),\n                                   multilineSpacing: multilineSpacing,\n                                   paddingInsets: paddingInsets,\n                                   alignment: config.alignment,\n                                   isRTL: config.isRTL\n            )\n        }\n        \n        guard config.shouldCenterVertically,\n              let maxY = currentSkeletonSublayers.last?.frame.maxY else {\n            return\n        }\n        let verticallyCenterAlignedFrames = currentSkeletonSublayers.map { layer -> CGRect in\n            let moveDownBy = (bounds.height - (maxY + paddingInsets.top + paddingInsets.bottom)) / 2\n            return layer.frame.offsetBy(dx: 0, dy: moveDownBy)\n        }\n        \n        for (index, layer) in currentSkeletonSublayers.enumerated() {\n            layer.frame = verticallyCenterAlignedFrames[index]\n        }\n    }\n\n    func updateLayerFrame(for index: Int, totalLines: Int, size: CGSize, multilineSpacing: CGFloat, paddingInsets: UIEdgeInsets, alignment: NSTextAlignment, isRTL: Bool) {\n        let spaceRequiredForEachLine = size.height + multilineSpacing\n        let newFrame = CGRect(x: paddingInsets.left,\n                              y: CGFloat(index) * spaceRequiredForEachLine + paddingInsets.top,\n                              width: size.width,\n                              height: size.height)\n\n        if index == totalLines - 1 {\n            frame = alignLayerFrame(newFrame, paddingInsets: paddingInsets, alignment: alignment, isRTL: isRTL)\n        } else {\n            frame = newFrame\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/SkeletonTreeNode+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonTreeNode+Extensions.swift\n//\n//  Created by Juanpe Catalán on 23/8/21.\n\nimport UIKit\n\nextension UIView: SkeletonViewExtended { }\n\nextension SkeletonTreeNode where Base: UIView {\n    \n    var children: [SkeletonTreeNode<UIView>] {\n        base.subviewsSkeletonables.map { $0.sk.treeNode }\n    }\n    \n    var parent: SkeletonTreeNode<UIView>? {\n        base.superview?.sk.treeNode\n    }\n    \n}\n\n// MARK: Debug\n\nextension SkeletonTreeNode where Base: UIView {\n    \n    var dictionaryRepresentation: [String: Any] {\n        let skeletonableChildren = children\n        \n        var nodeInfo: [String: Any] = [\n            \"type\": \"\\(type(of: base))\",\n            \"reference\": \"\\(Unmanaged.passUnretained(base).toOpaque())\",\n            \"isSkeletonable\": base.isSkeletonable\n        ]\n        \n        if !skeletonableChildren.isEmpty {\n            nodeInfo[\"children\"] = skeletonableChildren.map { $0.dictionaryRepresentation }\n        }\n        \n        return nodeInfo\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UICollectionView+CollectionSkeleton.swift",
    "content": "//\n//  UICollectionView+CollectionSkeleton.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/02/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n \nextension UICollectionView: CollectionSkeleton {\n\n    var estimatedNumberOfRows: Int {\n        guard let flowlayout = collectionViewLayout as? UICollectionViewFlowLayout else { return 0 }\n        switch flowlayout.scrollDirection {\n        case .vertical:\n            return Int(ceil(frame.height / flowlayout.itemSize.height))\n        case .horizontal:\n            return Int(ceil(frame.width / flowlayout.itemSize.width))\n        default:\n            return 0\n        }\n    }\n    \n    var skeletonDataSource: SkeletonCollectionDataSource? {\n        get { return ao_get(pkey: &CollectionAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }\n        set {\n            ao_setOptional(newValue, pkey: &CollectionAssociatedKeys.dummyDataSource)\n            self.dataSource = newValue\n        }\n    }\n    \n    var skeletonDelegate: SkeletonCollectionDelegate? {\n        get { return ao_get(pkey: &CollectionAssociatedKeys.dummyDelegate) as? SkeletonCollectionDelegate }\n        set {\n            ao_setOptional(newValue, pkey: &CollectionAssociatedKeys.dummyDelegate)\n            self.delegate = newValue\n        }\n    }\n    \n    func addDummyDataSource() {\n        guard let originalDataSource = self.dataSource as? SkeletonCollectionViewDataSource,\n            !(originalDataSource is SkeletonCollectionDataSource)\n            else { return }\n        \n        let dataSource = SkeletonCollectionDataSource(collectionViewDataSource: originalDataSource)\n        self.skeletonDataSource = dataSource\n        reloadData()\n    }\n    \n    func updateDummyDataSource() {\n        if (dataSource as? SkeletonCollectionDataSource) != nil {\n            reloadData()\n        } else {\n            addDummyDataSource()\n        }\n    }\n    \n    func removeDummyDataSource(reloadAfter: Bool) {\n        guard let dataSource = self.dataSource as? SkeletonCollectionDataSource else { return }\n        self.skeletonDataSource = nil\n        self.dataSource = dataSource.originalCollectionViewDataSource\n        if reloadAfter { self.reloadData() }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIColor+Skeleton.swift",
    "content": "//  Copyright © 2017 SkeletonView. All rights reserved.\n\nimport UIKit\n\n// codebeat:disable[TOO_MANY_IVARS]\npublic extension UIColor {\n    \n    static var greenSea     = UIColor(0x16a085)\n    static var turquoise    = UIColor(0x1abc9c)\n    static var emerald      = UIColor(0x2ecc71)\n    static var peterRiver   = UIColor(0x3498db)\n    static var amethyst     = UIColor(0x9b59b6)\n    static var wetAsphalt   = UIColor(0x34495e)\n    static var nephritis    = UIColor(0x27ae60)\n    static var belizeHole   = UIColor(0x2980b9)\n    static var wisteria     = UIColor(0x8e44ad)\n    static var midnightBlue = UIColor(0x2c3e50)\n    static var sunFlower    = UIColor(0xf1c40f)\n    static var carrot       = UIColor(0xe67e22)\n    static var alizarin     = UIColor(0xe74c3c)\n    static var clouds       = UIColor(0xecf0f1)\n    static var darkClouds   = UIColor(0x1c2325)\n    static var concrete     = UIColor(0x95a5a6)\n    static var flatOrange   = UIColor(0xf39c12)\n    static var pumpkin      = UIColor(0xd35400)\n    static var pomegranate  = UIColor(0xc0392b)\n    static var silver       = UIColor(0xbdc3c7)\n    static var asbestos     = UIColor(0x7f8c8d)\n    \n    static var skeletonDefault: UIColor {\n        if #available(iOS 13, tvOS 13, *) {\n            return UIColor { traitCollection in\n                switch traitCollection.userInterfaceStyle {\n                case .dark:\n                    return .darkClouds\n                default:\n                    return .clouds\n                }\n            }\n        } else {\n            return .clouds\n        }\n    }\n    \n    var complementaryColor: UIColor {\n        if #available(iOS 13, tvOS 13, *) {\n            return UIColor { _ in\n                self.isLight ? self.darker : self.lighter\n            }\n        } else {\n            return isLight ? darker : lighter\n        }\n    }\n    \n    var lighter: UIColor {\n        adjust(by: 1.35)\n    }\n    \n    var darker: UIColor {\n        adjust(by: 0.94)\n    }\n    \n}\n\nextension UIColor {\n    \n    convenience init(_ hex: UInt) {\n        self.init(\n            red: CGFloat((hex & 0xFF0000) >> 16) / 255.0,\n            green: CGFloat((hex & 0x00FF00) >> 8) / 255.0,\n            blue: CGFloat(hex & 0x0000FF) / 255.0,\n            alpha: CGFloat(1.0)\n        )\n    }\n    \n    var isLight: Bool {\n        guard let components = cgColor.components,\n            components.count >= 3 else { return false }\n        let brightness = ((components[0] * 299) + (components[1] * 587) + (components[2] * 114)) / 1000\n        return !(brightness < 0.5)\n    }\n    \n    func adjust(by percent: CGFloat) -> UIColor {\n        var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0\n        getHue(&h, saturation: &s, brightness: &b, alpha: &a)\n        return UIColor(hue: h, saturation: s, brightness: b * percent, alpha: a)\n    }\n    \n    func makeGradient() -> [UIColor] {\n        [self, self.complementaryColor, self]\n    }\n    \n}\n// codebeat:enable[TOO_MANY_IVARS]\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UILabel+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UILabel+Extensions.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\nextension UILabel {\n    \n    var desiredHeightBasedOnNumberOfLines: CGFloat {\n        let spaceNeededForEachLine = estimatedLineHeight * CGFloat(estimatedNumberOfLines)\n        let spaceNeededForSpaces = skeletonLineSpacing * CGFloat(estimatedNumberOfLines - 1)\n        let padding = paddingInsets.top + paddingInsets.bottom\n        \n        return spaceNeededForEachLine + spaceNeededForSpaces + padding\n    }\n    \n    func updateHeightConstraintsIfNeeded() {\n        guard estimatedNumberOfLines > 1 || estimatedNumberOfLines == 0 else { return }\n        \n        // Workaround to simulate content when the label is contained in a `UIStackView`.\n        if isSuperviewAStackView, bounds.height == 0, (text?.isEmpty ?? true) {\n            // This is a placeholder text to simulate content because it's contained in a stack view in order to prevent that the content size will be zero.\n            text = \" \"\n        }\n        \n        let desiredHeight = desiredHeightBasedOnNumberOfLines\n        if desiredHeight > definedMaxHeight {\n            backupHeightConstraints = heightConstraints\n            NSLayoutConstraint.deactivate(heightConstraints)\n            setHeight(equalToConstant: desiredHeight)\n        }\n    }\n    \n    func restoreBackupHeightConstraintsIfNeeded() {\n        guard !backupHeightConstraints.isEmpty else { return }\n        NSLayoutConstraint.activate(backupHeightConstraints)\n        backupHeightConstraints.removeAll()\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+CollectionSkeleton.swift",
    "content": "//\n//  UITableView+CollectionSkeleton.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/02/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nextension UITableView: CollectionSkeleton {\n\n    var estimatedNumberOfRows: Int {\n        return Int(ceil(frame.height / rowHeight))\n    }\n    \n    var skeletonDataSource: SkeletonCollectionDataSource? {\n        get { return ao_get(pkey: &CollectionAssociatedKeys.dummyDataSource) as? SkeletonCollectionDataSource }\n        set {\n            ao_setOptional(newValue, pkey: &CollectionAssociatedKeys.dummyDataSource)\n            self.dataSource = newValue\n        }\n    }\n    \n    var skeletonDelegate: SkeletonCollectionDelegate? {\n        get { return ao_get(pkey: &CollectionAssociatedKeys.dummyDelegate) as? SkeletonCollectionDelegate }\n        set {\n            ao_setOptional(newValue, pkey: &CollectionAssociatedKeys.dummyDelegate)\n            self.delegate = newValue\n        }\n    }\n    \n    func addDummyDataSource() {\n        guard let originalDataSource = self.dataSource as? SkeletonTableViewDataSource,\n            !(originalDataSource is SkeletonCollectionDataSource)\n            else { return }\n        let calculatedRowHeight = calculateRowHeight()\n        let dataSource = SkeletonCollectionDataSource(tableViewDataSource: originalDataSource,\n                                                      rowHeight: rowHeight,\n                                                      originalRowHeight: self.rowHeight)\n        rowHeight = calculatedRowHeight\n        self.skeletonDataSource = dataSource\n\n        if let originalDelegate = self.delegate as? SkeletonTableViewDelegate,\n            !(originalDelegate is SkeletonCollectionDelegate) {\n            let delegate = SkeletonCollectionDelegate(tableViewDelegate: originalDelegate)\n            self.skeletonDelegate = delegate\n        }\n\n        reloadData()\n    }\n    \n    func updateDummyDataSource() {\n        if (dataSource as? SkeletonCollectionDataSource) != nil {\n            reloadData()\n        } else {\n            addDummyDataSource()\n        }\n    }\n    \n    func removeDummyDataSource(reloadAfter: Bool) {\n        guard let dataSource = self.dataSource as? SkeletonCollectionDataSource else { return }\n        restoreRowHeight()\n        self.skeletonDataSource = nil\n        self.dataSource = dataSource.originalTableViewDataSource\n\n        if let delegate = self.delegate as? SkeletonCollectionDelegate {\n            self.skeletonDelegate = nil\n            self.delegate = delegate.originalTableViewDelegate\n        }\n\n        if reloadAfter { self.reloadData() }\n    }\n    \n}\n\nprivate extension UITableView {\n    \n    func restoreRowHeight() {\n        guard let dataSource = self.dataSource as? SkeletonCollectionDataSource else { return }\n        rowHeight = dataSource.originalRowHeight\n    }\n    \n    func calculateRowHeight() -> CGFloat {\n        guard rowHeight == UITableView.automaticDimension else { return rowHeight }\n        return estimatedRowHeight\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UITableView+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UITableView+Extensions.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\nextension UITableView {\n    \n    var indexesOfVisibleSections: [Int] {\n        (0..<numberOfSections).reduce([]) {\n            let headerRect = style == .plain ? rect(forSection: $1) : rectForHeader(inSection: $1)\n            \n            let visiblePartOfTableView = CGRect(\n                x: contentOffset.x,\n                y: contentOffset.y,\n                width: bounds.size.width,\n                height: bounds.size.height\n            )\n            \n            if visiblePartOfTableView.intersects(headerRect) {\n                return $0 + [$1]\n            }\n            \n            return $0\n        }\n    }\n\n    var visibleSectionHeaders: [UITableViewHeaderFooterView] {\n        indexesOfVisibleSections.compactMap { headerView(forSection: $0) }\n    }\n    \n    var visibleSectionFooters: [UITableViewHeaderFooterView] {\n        indexesOfVisibleSections.compactMap { footerView(forSection: $0) }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+AppLifecycleNotifications.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+AppLifecycleNotifications.swift\n//\n//  Created by Juanpe Catalán on 08/02/2018.\n\nimport UIKit\n\nextension UIView {\n    \n    enum Constants {\n        static let needAnimatedSkeletonKey = \"needAnimateSkeleton\"\n    }\n    \n    func startObservingAppLifecycleNotifications() {\n        NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive), name: .applicationDidBecomeActiveNotification, object: nil)\n        NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: .applicationDidEnterForegroundNotification, object: nil)\n        NotificationCenter.default.addObserver(self, selector: #selector(willTerminateNotification), name: .applicationWillTerminateNotification, object: nil)\n    }\n    \n    func stopObservingAppLifecycleNotications() {\n        NotificationCenter.default.removeObserver(self, name: .applicationDidBecomeActiveNotification, object: nil)\n        NotificationCenter.default.removeObserver(self, name: .applicationDidEnterForegroundNotification, object: nil)\n        NotificationCenter.default.removeObserver(self, name: .applicationWillTerminateNotification, object: nil)\n    }\n    \n    @objc func appDidBecomeActive() {\n        if UserDefaults.standard.bool(forKey: Constants.needAnimatedSkeletonKey) {\n            startSkeletonAnimation()\n        }\n    }\n    \n    @objc func appDidEnterBackground() {\n        UserDefaults.standard.set((sk.isSkeletonActive && _isSkeletonAnimated), forKey: Constants.needAnimatedSkeletonKey)\n    }\n    \n    @objc func willTerminateNotification() {\n        UserDefaults.standard.set(false, forKey: Constants.needAnimatedSkeletonKey)\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+AssociatedObjects.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+AssociatedObjects.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\n// codebeat:disable[TOO_MANY_IVARS]\nenum ViewAssociatedKeys {\n    \n    static var skeletonable = \"skeletonable\"\n    static var hiddenWhenSkeletonIsActive = \"hiddenWhenSkeletonIsActive\"\n    static var status = \"status\"\n    static var skeletonLayer = \"layer\"\n    static var flowDelegate = \"flowDelegate\"\n    static var isSkeletonAnimated = \"isSkeletonAnimated\"\n    static var viewState = \"viewState\"\n    static var labelViewState = \"labelViewState\"\n    static var imageViewState = \"imageViewState\"\n    static var buttonViewState = \"buttonViewState\"\n    static var headerFooterViewState = \"headerFooterViewState\"\n    static var currentSkeletonConfig = \"currentSkeletonConfig\"\n    static var skeletonCornerRadius = \"skeletonCornerRadius\"\n    static var disabledWhenSkeletonIsActive = \"disabledWhenSkeletonIsActive\"\n    static var delayedShowSkeletonWorkItem = \"delayedShowSkeletonWorkItem\"\n    \n}\n// codebeat:enable[TOO_MANY_IVARS]\n\nextension UIView {\n    \n    enum SkeletonStatus {\n        case on\n        case off\n    }\n\n    var _flowDelegate: SkeletonFlowDelegate? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.flowDelegate) as? SkeletonFlowDelegate }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.flowDelegate) }\n    }\n\n    var _skeletonLayer: SkeletonLayer? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.skeletonLayer) as? SkeletonLayer }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.skeletonLayer) }\n    }\n\n    var _currentSkeletonConfig: SkeletonConfig? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.currentSkeletonConfig) as? SkeletonConfig }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.currentSkeletonConfig) }\n    }\n\n    var _status: SkeletonStatus {\n        get { return ao_get(pkey: &ViewAssociatedKeys.status) as? SkeletonStatus ?? .off }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.status) }\n    }\n\n    var _isSkeletonAnimated: Bool {\n        get { return ao_get(pkey: &ViewAssociatedKeys.isSkeletonAnimated) as? Bool ?? false }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.isSkeletonAnimated) }\n    }\n    \n    var _delayedShowSkeletonWorkItem: DispatchWorkItem? {\n        get { return ao_get(pkey: &ViewAssociatedKeys.delayedShowSkeletonWorkItem) as? DispatchWorkItem }\n        set { ao_setOptional(newValue, pkey: &ViewAssociatedKeys.delayedShowSkeletonWorkItem) }\n    }\n    \n    var _skeletonable: Bool {\n        get { return ao_get(pkey: &ViewAssociatedKeys.skeletonable) as? Bool ?? false }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.skeletonable) }\n    }\n    \n    var _hiddenWhenSkeletonIsActive: Bool {\n        get { return ao_get(pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) as? Bool ?? false }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.hiddenWhenSkeletonIsActive) }\n    }\n    \n    var _disabledWhenSkeletonIsActive: Bool {\n        get { return ao_get(pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) as? Bool ?? true }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.disabledWhenSkeletonIsActive) }\n    }\n\n    var _skeletonableCornerRadius: Float {\n        get { return ao_get(pkey: &ViewAssociatedKeys.skeletonCornerRadius) as? Float ?? SkeletonViewAppearance.shared.skeletonCornerRadius }\n        set { ao_set(newValue, pkey: &ViewAssociatedKeys.skeletonCornerRadius) }\n    }\n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+CollectionSkeleton.swift",
    "content": "//\n//  UIView+CollectionSkeleton.swift\n//  SkeletonView-iOS\n//\n//  Created by Juanpe Catalán on 02/02/2018.\n//  Copyright © 2018 SkeletonView. All rights reserved.\n//\n\nimport UIKit\n\nextension UIView {\n    \n    func addDummyDataSourceIfNeeded() {\n        guard let collection = self as? CollectionSkeleton,\n            !ProcessInfo.isRunningXCTest else { return }\n        _status = .on\n        collection.addDummyDataSource()\n        collection.disableUserInteraction()\n    }\n    \n    func updateDummyDataSourceIfNeeded() {\n        guard let collection = self as? CollectionSkeleton,\n            !ProcessInfo.isRunningXCTest else { return }\n        collection.updateDummyDataSource()\n    }\n    \n    func removeDummyDataSourceIfNeeded(reloadAfter reload: Bool = true) {\n        guard let collection = self as? CollectionSkeleton,\n            !ProcessInfo.isRunningXCTest else { return }\n        _status = .off\n        collection.removeDummyDataSource(reloadAfter: reload)\n        collection.enableUserInteraction()\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Extensions.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+Extensions.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport UIKit\n\nextension SkeletonViewExtension where ExtendedType: UIView {\n    \n    var treeNode: SkeletonTreeNode<ExtendedType> {\n        SkeletonTreeNode<ExtendedType>(self.type)\n    }\n    \n}\n\nextension UIView {\n\n    /// Flags\n    \n    var isSuperviewAStackView: Bool {\n        superview is UIStackView\n    }\n    \n    var isRTL: Bool {\n        if #available(iOS 10.0, *), #available(tvOS 10.0, *) {\n            return effectiveUserInterfaceLayoutDirection == .rightToLeft\n        } else {\n            return false\n        }\n    }\n    \n    /// Math\n    \n    var definedMaxBounds: CGRect {\n        if let parentStackView = (superview as? UIStackView) {\n            var origin: CGPoint = .zero\n            switch parentStackView.alignment {\n            case .trailing:\n                origin.x = definedMaxWidth\n            default:\n                break\n            }\n            return CGRect(origin: origin, size: definedMaxSize)\n        }\n        return CGRect(origin: .zero, size: definedMaxSize)\n    }\n    \n    var definedMaxSize: CGSize {\n        CGSize(width: definedMaxWidth, height: definedMaxHeight)\n    }\n    \n    var definedMaxWidth: CGFloat {\n        let constraintsMaxWidth = widthConstraints\n            .map { $0.constant }\n            .max() ?? 0\n\n        return max(frame.size.width, constraintsMaxWidth)\n    }\n    \n    var definedMaxHeight: CGFloat {\n        let constraintsMaxHeight = heightConstraints\n            .map { $0.constant }\n            .max() ?? 0\n\n        return max(frame.size.height, constraintsMaxHeight)\n    }\n    \n    /// Autolayout\n    \n    var widthConstraints: [NSLayoutConstraint] {\n        nonContentSizeLayoutConstraints.filter { $0.firstAttribute == NSLayoutConstraint.Attribute.width }\n    }\n    \n    var heightConstraints: [NSLayoutConstraint] {\n        nonContentSizeLayoutConstraints.filter { $0.firstAttribute == NSLayoutConstraint.Attribute.height }\n    }\n    \n    var skeletonHeightConstraints: [NSLayoutConstraint] {\n        nonContentSizeLayoutConstraints.filter {\n            $0.firstAttribute == NSLayoutConstraint.Attribute.height\n                && $0.identifier?.contains(\"SkeletonView.Constraint.Height\") ?? false\n        }\n    }\n    \n    @discardableResult\n    func setHeight(equalToConstant constant: CGFloat) -> NSLayoutConstraint {\n        let heightConstraint = heightAnchor.constraint(equalToConstant: constant)\n        heightConstraint.identifier = \"SkeletonView.Constraint.Height.\\(constant)\"\n        NSLayoutConstraint.activate([heightConstraint])\n        return heightConstraint\n    }\n    \n    var nonContentSizeLayoutConstraints: [NSLayoutConstraint] {\n        constraints.filter({ \"\\(type(of: $0))\" != \"NSContentSizeLayoutConstraint\" })\n    }\n    \n    /// Animations\n    \n    func startSkeletonLayerAnimationBlock(_ anim: SkeletonLayerAnimation? = nil) -> VoidBlock {\n        {\n            self._isSkeletonAnimated = true\n            guard let layer = self._skeletonLayer else { return }\n            layer.start(anim) { [weak self] in\n                self?._isSkeletonAnimated = false\n            }\n        }\n    }\n    \n    var stopSkeletonLayerAnimationBlock: VoidBlock {\n        {\n            self._isSkeletonAnimated = false\n            guard let layer = self._skeletonLayer else { return }\n            layer.stopAnimation()\n        }\n    }\n    \n    /// Skeleton Layer\n    \n    func addSkeletonLayer(skeletonConfig config: SkeletonConfig) {\n        guard let skeletonLayer = SkeletonLayerBuilder()\n            .setSkeletonType(config.type)\n            .addColors(config.colors)\n            .setHolder(self)\n            .build()\n            else { return }\n        \n        self._skeletonLayer = skeletonLayer\n        layer.insertSkeletonLayer(\n            skeletonLayer,\n            atIndex: UInt32.max,\n            transition: config.transition\n        ) { [weak self] in\n            guard let self = self else { return }\n            \n            // Workaround to fix the problem when inserting a sublayer and\n            // the content offset is modified by the system.\n            (self as? UITextView)?.setContentOffset(.zero, animated: false)\n            \n            if config.animated {\n                self.startSkeletonAnimation(config.animation)\n            }\n        }\n        _status = .on\n    }\n    \n    func updateSkeletonLayer(skeletonConfig config: SkeletonConfig) {\n        guard let skeletonLayer = _skeletonLayer else { return }\n        skeletonLayer.update(usingColors: config.colors)\n        if config.animated {\n            startSkeletonAnimation(config.animation)\n        } else {\n            skeletonLayer.stopAnimation()\n        }\n    }\n\n    func layoutSkeletonLayerIfNeeded() {\n        guard let skeletonLayer = _skeletonLayer else { return }\n        skeletonLayer.layoutIfNeeded()\n    }\n    \n    func removeSkeletonLayer() {\n        guard sk.isSkeletonActive,\n            let skeletonLayer = _skeletonLayer,\n            let transitionStyle = _currentSkeletonConfig?.transition else { return }\n        skeletonLayer.stopAnimation()\n        _status = .off\n        skeletonLayer.removeLayer(transition: transitionStyle) {\n            self._skeletonLayer = nil\n            self._currentSkeletonConfig = nil\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+SkeletonView.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+SkeletonView.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\nextension UIView {\n    \n    func showSkeleton(\n        skeletonConfig config: SkeletonConfig,\n        notifyDelegate: Bool = true\n    ) {\n        _isSkeletonAnimated = config.animated\n        \n        if notifyDelegate {\n            _flowDelegate = SkeletonFlowHandler()\n            _flowDelegate?.willBeginShowingSkeletons(rootView: self)\n        }\n        \n        recursiveShowSkeleton(skeletonConfig: config, root: self)\n    }\n\n    func updateSkeleton(\n        skeletonConfig config: SkeletonConfig,\n        notifyDelegate: Bool = true\n    ) {\n        _isSkeletonAnimated = config.animated\n        \n        if notifyDelegate {\n            _flowDelegate?.willBeginUpdatingSkeletons(rootView: self)\n        }\n        \n        recursiveUpdateSkeleton(skeletonConfig: config, root: self)\n    }\n\n    func recursiveLayoutSkeletonIfNeeded(root: UIView? = nil) {\n        subviewsSkeletonables.recursiveSearch(leafBlock: {\n            guard isSkeletonable, sk.isSkeletonActive else { return }\n            layoutSkeletonLayerIfNeeded()\n            if let config = _currentSkeletonConfig, config.animated, !_isSkeletonAnimated {\n                startSkeletonAnimation(config.animation)\n            }\n        }) { subview in\n            subview.recursiveLayoutSkeletonIfNeeded()\n        }\n\n        if let root = root {\n            _flowDelegate?.didLayoutSkeletonsIfNeeded(rootView: root)\n        }\n    }\n\n    func recursiveHideSkeleton(reloadDataAfter reload: Bool, transition: SkeletonTransitionStyle, root: UIView? = nil) {\n        guard sk.isSkeletonActive else { return }\n        if isHiddenWhenSkeletonIsActive {\n            isHidden = false\n        }\n        _currentSkeletonConfig?.transition = transition\n        unSwizzleLayoutSubviews()\n        unSwizzleTraitCollectionDidChange()\n        removeDummyDataSourceIfNeeded(reloadAfter: reload)\n        subviewsSkeletonables.recursiveSearch(leafBlock: {\n            recoverViewState(forced: false)\n            removeSkeletonLayer()\n        }) { subview in\n            subview.recursiveHideSkeleton(reloadDataAfter: reload, transition: transition)\n        }\n        \n        if let root = root {\n            _flowDelegate?.didHideSkeletons(rootView: root)\n        }\n    }\n    \n}\n\nprivate extension UIView {\n    \n    func showSkeletonIfNotActive(skeletonConfig config: SkeletonConfig) {\n        guard !sk.isSkeletonActive else { return }\n        saveViewState()\n\n        prepareViewForSkeleton()\n        addSkeletonLayer(skeletonConfig: config)\n    }\n    \n    func recursiveShowSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {\n        if isHiddenWhenSkeletonIsActive {\n            isHidden = true\n        }\n        guard isSkeletonable && !sk.isSkeletonActive else { return }\n        _currentSkeletonConfig = config\n        swizzleLayoutSubviews()\n        swizzleTraitCollectionDidChange()\n        addDummyDataSourceIfNeeded()\n        subviewsSkeletonables.recursiveSearch(leafBlock: {\n            showSkeletonIfNotActive(skeletonConfig: config)\n        }) { subview in\n            subview.recursiveShowSkeleton(skeletonConfig: config)\n        }\n\n        if let root = root {\n            _flowDelegate?.didShowSkeletons(rootView: root)\n        }\n    }\n    \n    func recursiveUpdateSkeleton(skeletonConfig config: SkeletonConfig, root: UIView? = nil) {\n        guard sk.isSkeletonActive else { return }\n        _currentSkeletonConfig = config\n        updateDummyDataSourceIfNeeded()\n        subviewsSkeletonables.recursiveSearch(leafBlock: {\n            if let skeletonLayer = _skeletonLayer,\n                skeletonLayer.type != config.type {\n                removeSkeletonLayer()\n                addSkeletonLayer(skeletonConfig: config)\n            } else {\n                updateSkeletonLayer(skeletonConfig: config)\n            }\n        }) { subview in\n            subview.recursiveUpdateSkeleton(skeletonConfig: config)\n        }\n\n        if let root = root {\n            _flowDelegate?.didUpdateSkeletons(rootView: root)\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Swizzling.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  UIView+Swizzling.swift\n//\n//  Created by Juanpe Catalán on 19/8/21.\n\nimport UIKit\n\nextension UIView {\n\n    @objc func skeletonLayoutSubviews() {\n        guard Thread.isMainThread else { return }\n        skeletonLayoutSubviews()\n        guard sk.isSkeletonActive else { return }\n        layoutSkeletonIfNeeded()\n    }\n\n    @objc func skeletonTraitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {\n        skeletonTraitCollectionDidChange(previousTraitCollection)\n        guard isSkeletonable, sk.isSkeletonActive, let config = _currentSkeletonConfig else { return }\n        updateSkeleton(skeletonConfig: config)\n    }\n    \n    func swizzleLayoutSubviews() {\n        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {\n            DispatchQueue.once(token: \"UIView.SkeletonView.swizzleLayoutSubviews\") {\n                swizzle(selector: #selector(UIView.layoutSubviews),\n                        with: #selector(UIView.skeletonLayoutSubviews),\n                        inClass: UIView.self,\n                        usingClass: UIView.self)\n                self.layoutSkeletonIfNeeded()\n            }\n        }\n    }\n    \n    func unSwizzleLayoutSubviews() {\n        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {\n            DispatchQueue.removeOnce(token: \"UIView.SkeletonView.swizzleLayoutSubviews\") {\n                swizzle(selector: #selector(UIView.skeletonLayoutSubviews),\n                        with: #selector(UIView.layoutSubviews),\n                        inClass: UIView.self,\n                        usingClass: UIView.self)\n            }\n        }\n    }\n    \n    func swizzleTraitCollectionDidChange() {\n        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {\n            DispatchQueue.once(token: \"UIView.SkeletonView.swizzleTraitCollectionDidChange\") {\n                swizzle(selector: #selector(UIView.traitCollectionDidChange(_:)),\n                        with: #selector(UIView.skeletonTraitCollectionDidChange(_:)),\n                        inClass: UIView.self,\n                        usingClass: UIView.self)\n            }\n        }\n    }\n    \n    func unSwizzleTraitCollectionDidChange() {\n        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {\n            DispatchQueue.removeOnce(token: \"UIView.SkeletonView.swizzleTraitCollectionDidChange\") {\n                swizzle(selector: #selector(UIView.skeletonTraitCollectionDidChange(_:)),\n                        with: #selector(UIView.traitCollectionDidChange(_:)),\n                        inClass: UIView.self,\n                        usingClass: UIView.self)\n            }\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Internal/UIKitExtensions/UIView+Transitions.swift",
    "content": "// Copyright © 2019 SkeletonView. All rights reserved.\n\nimport UIKit\n\nextension UIView {\n    \n    func startTransition(transitionBlock: @escaping () -> Void) {\n        guard let transitionStyle = _currentSkeletonConfig?.transition,\n              transitionStyle != .none else {\n            transitionBlock()\n            return\n        }\n        \n        if case let .crossDissolve(duration) = transitionStyle {\n            UIView.transition(with: self,\n                              duration: duration,\n                              options: .transitionCrossDissolve,\n                              animations: transitionBlock,\n                              completion: nil)\n        }\n    }\n    \n}\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Supporting Files/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>$(EXECUTABLE_NAME)</string>\n  <key>CFBundleIdentifier</key>\n  <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>$(PRODUCT_NAME)</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>$(CURRENT_PROJECT_VERSION)</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "SkeletonViewCore/Sources/Supporting Files/PrivacyInfo.xcprivacy",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>NSPrivacyTracking</key>\n\t<false/>\n\t<key>NSPrivacyTrackingDomains</key>\n\t<array/>\n\t<key>NSPrivacyCollectedDataTypes</key>\n\t<array/>\n\t<key>NSPrivacyAccessedAPITypes</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>NSPrivacyAccessedAPIType</key>\n\t\t\t<string>NSPrivacyAccessedAPICategoryUserDefaults</string>\n\t\t\t<key>NSPrivacyAccessedAPITypeReasons</key>\n\t\t\t<array>\n\t\t\t\t<string>CA92.1</string>\n\t\t\t</array>\n\t\t</dict>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "SkeletonViewCore/Tests/Debug/SkeletonDebugTests.swift",
    "content": "//\n//  Copyright SkeletonView. All Rights Reserved.\n//\n//  Licensed under the MIT License (the \"License\");\n//  you may not use this file except in compliance with the License.\n//  You may obtain a copy of the License at\n//\n//      https://opensource.org/licenses/MIT\n//\n//  SkeletonDebugTests.swift\n//\n//  Created by Juanpe Catalán on 18/8/21.\n\nimport XCTest\n@testable import SkeletonView\n\nclass SkeletonDebugTests: XCTestCase {\n\n    func testSkeletonDescriptionWithViewNotSkeletonableNotReturnsSkullEmojiAndChildren() {\n        /// given\n        let view = UIView()\n        let expectedDictionary: [String : Any] = [\n            \"isSkeletonable\" : false,\n            \"type\" : \"UIView\",\n            \"reference\" : \"\\(Unmanaged.passUnretained(view).toOpaque())\"\n        ]\n        \n        /// when\n        let obtainedDictionary = view.sk.treeNode.dictionaryRepresentation\n        \n        /// then\n        XCTAssertEqual(expectedDictionary.keys, obtainedDictionary.keys)\n    }\n\n}\n"
  },
  {
    "path": "SkeletonViewCore/Tests/Supporting Files/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>en</string>\n  <key>CFBundleExecutable</key>\n  <string>$(EXECUTABLE_NAME)</string>\n  <key>CFBundleIdentifier</key>\n  <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>$(PRODUCT_NAME)</string>\n  <key>CFBundlePackageType</key>\n  <string>BNDL</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>$(CURRENT_PROJECT_VERSION)</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Translations/README_de.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-main\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/1f37bbab-a1c8-4a4a-94d7-f21740d461e9\" /></a>\n    <a href=\"https://cocoapods.org/pods/SkeletonView\"><img src=\"https://img.shields.io/cocoapods/v/SkeletonView.svg?style=flat\"></a>\n    <a href=\"https://github.com/Carthage/Carthage/\"><img src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\"></a>\n    <a href=\"https://swift.org/package-manager/\"><img src=\"https://img.shields.io/badge/SPM-supported-Green.svg?style=flat\"></a>\n    <img src=\"https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FJuanpe%2FSkeletonView%2Fbadge%3Ftype%3Dplatforms\"/>\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.20.0\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n</p>\n\n<p align=\"center\">\n    <a href=\"#-funktionen\">Funktionen</a>\n  • <a href=\"#-anleitungen\">Anleitungen</a>\n  • <a href=\"#-installation\">Installation</a>\n  • <a href=\"#-verwendung\">Verwendung</a>\n  • <a href=\"#-sonstiges\">Sonstiges</a>\n  • <a href=\"#️-beitragen\">Beitragen</a>\n</p>\n\n**🌎 README ist auch in anderen Sprachen verfügbar: [🇬🇧](../README.md) . [🇪🇸](README_es.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md)**\n\nHeutzutage haben fast alle Anwendungen async-Prozesse, z.B. API-Anfragen, lang laufende Prozesse, usw. Während die Prozesse arbeiten, platzieren die Entwickler in der Regel eine Ladeansicht, um den Benutzern zu zeigen, dass im Hintergrund etwas vor sich geht.\n\n**SkeletonView** wurde entwickelt, um dieses Bedürfnis zu befriedigen, indem auf eine elegante Art und Weise den Nutzern gezeigt wird, dass etwas passiert und sie gleichzeitig darauf vorbereitet, welche Inhalte sie erwarten.\n\nViel Spaß damit! 🙂\n\n##\n\n- [🌟 Funktionen](#-funktionen)\n- [🎬 Anleitungen](#-anleitungen)\n- [📲 Installation](#-installation)\n- [🐒 Verwendung](#-verwendung)\n  - [🌿 Sammlungen](#-sammlungen)\n  - [🔠 Texte](#-texte)\n  - [🦋 Erscheinungsbild](#-erscheinungsbild)\n  - [🎨 Benutzerdefinierte Farben](#-benutzerdefinierte-farben)\n  - [🏃‍♀️ Animationen](#️-animationen)\n  - [🏄 Übergänge](#-übergänge)\n- [✨ Sonstiges](#-sonstiges)\n- [❤️ Beitragen](#️-beitragen)\n- [📢 Erwähnungen](#-erwähnungen)\n- [🏆 Sponsoren](#-sponsoren)\n- [👨🏻‍💻 Autor](#-autor)\n- [👮🏻 Lizenz](#-lizenz)\n\n\n\n## 🌟 Funktionen\n\n* Einfach zu benutzen\n* Alle UIViews sind skelettierbar\n* Vollständig anpassbar\n* Universal (iPhone & iPad)\n* Freundlicher interface builder\n* Einfache Swift-Syntax\n* Leicht lesbarer code\n\n\n## 🎬 Anleitungen\n\n| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/Zx1Pg1gPfxA/maxresdefault.jpg)](https://www.youtube.com/watch?v=Zx1Pg1gPfxA)\n|:---:  | :---:  | :---: | :---:\n|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA)    by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8)    by iOS Academy| [**Cómo crear una ANIMACIÓN de CARGA de DATOS en iOS**](https://www.youtube.com/watch?v=Zx1Pg1gPfxA) by MoureDev\n\n\n## 📲 Installation\n\n* [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html):\n\n```ruby\npod 'SkeletonView'\n```\n\n* [Carthage](https://github.com/Carthage/Carthage):\n\n```ruby\ngithub \"Juanpe/SkeletonView\"\n```\n\n* [Swift Package Manager](https://swift.org/package-manager/):\n\n```swift\ndependencies: [\n  .package(url: \"https://github.com/Juanpe/SkeletonView.git\", from: \"1.7.0\")\n]\n```\n\n> 📣 **WICHTIG!**\n>\n> Seit Version 1.30.0 unterstützt `SkeletonView` **XCFrameworks**, wenn du es also als **XCFramework** installieren möchtest, verwende bitte stattdessen [dieses Repo](https://github.com/Juanpe/SkeletonView-XCFramework.git).\n\n## 🐒 Verwendung\n\nNur **3** Schritte sind erforderlich, um `SkeletonView` zu verwenden:\n\n1️⃣ Importiere SkeletonView an der richtigen Stelle.\n\n```swift\nimport SkeletonView\n```\n\n2️⃣ Lege nun fest, welche Ansichten `skelettierbar` sein sollen. Dies kannst du auf zwei Arten erreichen:\n\n**Durch code:**\n\n```swift\navatarImageView.isSkeletonable = true\n```\n\n**Durch IB/Storyboards:**\n\n![](../Assets/storyboard.png)\n\n3️⃣ Sobald du die Views eingestellt hast, kannst du das **Skelett** anzeigen. Dazu hast du **4** Auswahlmöglichkeiten:\n\n```swift\n(1) view.showSkeleton()                 // Einfarbig\n(2) view.showGradientSkeleton()         // Farbverlauf\n(3) view.showAnimatedSkeleton()         // Einfarbig animiert\n(4) view.showAnimatedGradientSkeleton() // Farbverlauf animiert\n```\n\n**Vorschau**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Einfarbig</center>\n</td>\n<td width=\"25%\">\n<center>Farbverlauf</center>\n</td>\n<td width=\"25%\">\n<center>Einfarbig animiert</center>\n</td>\n<td width=\"25%\">\n<center>Farbverlauf animiert</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n> 📣 **WICHTIG!**\n>\n> `SkeletonView` ist rekursiv, wenn du also das Skelett in allen skelettierbaren Views anzeigen willst, musst du nur die show-Methode in der Haupt-Container-View aufrufen. Zum Beispiel mit `UIViewControllers`.\n\n### 🌿 Sammlungen\n\n```SkeletonView``` ist kompatibel mit ```UITableView``` und ```UICollectionView```.\n\n**UITableView**\n\nWenn du das Skelett in ```UITableView```'s anzeigen willst, müssen diese dem ```SkeletonTableViewDataSource```-Protokoll entsprechen.\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int // Standard: 1\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? // Standard: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath)\n}\n```\n\nWie du sehen kannst, erbt dieses Protokoll von ```UITableViewDataSource```, so dass du dieses Protokoll durch das Skelettprotokoll ersetzen kannst.\n\nDieses Protokoll hat eine Standardimplementierung für einige Methoden. Zum Beispiel wird die Anzahl der Zeilen für jeden Abschnitt in Echtzeit berechnet:\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// Standard:\n// Es wird berechnet, wie viele Zellen benötigt werden, um die gesamte Tabellenansicht zu füllen\n```\n\n> 📣 **WICHTIG!**\n>\n> Wenn du in der obigen Methode `UITableView.automaticNumberOfSkeletonRows` zurückgibst, verhält es sich wie das Standardverhalten (d.h. es wird berechnet, wie viele Zellen benötigt werden, um den gesamten Tableview zu füllen).\n\nEs gibt nur eine Methode, die du implementieren musst, damit Skeleton die Zellen ID kennt. Diese Methode hat keine Standardimplementierung:\n\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n\nStandardmäßig entfernt die library die Zellen aus jedem indexPath, aber du kannst dies auch tun, wenn du einige Änderungen vornehmen möchtest, bevor das Skelett erscheint:\n\n``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {\n     let cell = skeletonView.dequeueReusableCell(withIdentifier: \"CellIdentifier\", for: indexPath) as? Cell\n     cell?.textField.isHidden = indexPath.row == 0\n     return cell\n }\n ```\n\nWenn du es vorziehst, den deque-Teil der Bibliothek zu überlassen, kannst du die Zelle mit dieser Methode konfigurieren:\n\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, prepareCellForSkeleton cell: UITableViewCell, at indexPath: IndexPath) {\n     let cell = cell as? Cell\n     cell?.textField.isHidden = indexPath.row == 0\n }\n ```\n\nAußerdem kannst du sowohl die Kopf- als auch die Fußzeilen skelettieren. Diese müssen nur dem Protokoll \"SkeletonTableViewDelegate\" entsprechen.\n\n```swift\npublic protocol SkeletonTableViewDelegate: UITableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // standard: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // standard: nil\n}\n```\n\n> 📣 **WICHTIG!**\n>\n> 1️⃣ Wenn du größenvariable Zellen verwendest (**`tableView.rowHeight = UITableViewAutomaticDimension`**), ist es zwingend erforderlich, die **`estimatedRowHeight`** zu definieren.\n>\n> 2️⃣ Wenn man Elemente in einer **`UITableViewCell`** hinzufügt, sollte man sie dem **`contentView`** hinzufügen und nicht direkt in der Zelle.\n>\n> ```swift\n> self.contentView.addSubview(titleLabel) ✅         \n> self.addSubview(titleLabel) ❌\n> ```\n\n**UICollectionView**\n\nFür `UICollectionView` musst du dem Protokoll `SkeletonCollectionViewDataSource` entsprechen.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int  // standard: 1\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // standard: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, skeletonCellForItemAt indexPath: IndexPath) -> UICollectionViewCell?  // standard: nil\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareCellForSkeleton cell: UICollectionViewCell, at indexPath: IndexPath)\n    func collectionSkeletonView(_ skeletonView: UICollectionView, prepareViewForSkeleton view: UICollectionReusableView, at indexPath: IndexPath)\n}\n```\n\nDer Rest des Prozesses ist derselbe wie bei ```UITableView```\n\n### 🔠 Texte\n\n![](../Assets/multilines2.png)\n\nWenn Elemente mit Text verwendet werden, zeichnet ```SkeletonView``` Linien, um Text zu simulieren.\n\nDu kannst einige Variablen für mehrzeilige Elemente einstellen.\n\n| Variable | Typ | Standard | Vorschau\n| ------- | ------- |------- | -------\n| **lastLineFillPercent**  | `CGFloat` | `70`| ![](../Assets/multiline_lastline.png)\n| **linesCornerRadius**  | `Int` | `0` | ![](../Assets/multiline_corner.png)\n| **skeletonLineSpacing**  | `CGFloat` | `10` | ![](../Assets/multiline_lineSpacing.png)\n| **skeletonPaddingInsets**  | `UIEdgeInsets` | `.zero` | ![](../Assets/multiline_insets.png)\n| **skeletonTextLineHeight**  | `SkeletonTextLineHeight` | `.fixed(15)` | ![](../Assets/multiline_lineHeight.png)\n| **skeletonTextNumberOfLines**  | `SkeletonTextNumberOfLines` | `.inherited` | ![](../Assets/multiline_corner.png)\n\n<br />\n\nUm den Prozentsatz oder den Radius **mit Hilfe von Code** zu ändern, lege diese Variablen fest:\n\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\nOder, wenn du es vorziehst, verwende **IB/Storyboard**:\n\n![](../Assets/multiline_customize.png)\n\n<br />\n\n**Wie kann die Anzahl der Zeilen festgelegt werden?**\n\nStandardmäßig entspricht die Anzahl der Linien dem Wert der Variable `numberOfLines`. Und wenn es auf **null** gesetzt ist, wird berechnet, wie viele Linien benötigt werden, um das gesamte Skelett zu füllen und es zu zeichnen.\n\nWenn du jedoch eine bestimmte Anzahl von Zeilen für das Skelett festlegen möchtest, kannst du dies mit der Variable `skeletonTextNumberOfLines` tun. Diese Variable hat zwei mögliche Werte: `inherited`, der den Wert `numberOfLines` zurückgibt, und `custom(Int)`, der die spezifische Anzahl von Zeilen zurückgibt, die als zugehöriger Wert angegeben wurde.\n\nZum Beispiel:\n\n```swift\nlabel.skeletonTextNumberOfLines = 3   // .custom(3)\n```\n\n<br />\n\n> **⚠️ VERALTET!**\n>\n> **useFontLineHeight** wurde abgeschafft. Du kannst stattdessen **skeletonTextLineHeight** verwenden:\n>\n> ```swift\n> descriptionTextView.skeletonTextLineHeight = .relativeToFont\n> ```\n\n> **📣 WICHTIG!**\n>\n> Bitte beachte, dass bei Ansichten ohne mehrere Zeilen die einzelne Zeile\n> als letzte Zeile betrachtet wird.\n\n### 🦋 Erscheinungsbild\n\nDie Skelette haben ein Standardaussehen. Wenn du also die Farbe, den Farbverlauf oder Mehrlinien-Eigenschaften nicht angibst, verwendet `SkeletonView` die Standardwerte.\n\nStandardwerte:\n\n- **tintColor**: `UIColor`\n  - *standard: `.skeletonDefault` (gleich wie `.clouds`, aber anpassungsfähig an den dunklen Modus)*\n- **gradient**: SkeletonGradient\n  - *standard: `SkeletonGradient(baseColor: .skeletonDefault)`*\n- **multilineHeight**: `CGFloat`\n  - *standard: 15*\n- **multilineSpacing**: `CGFloat`\n  - *standard: 10*\n- **multilineLastLineFillPercent**: `Int`\n  - *standard: 70*\n- **multilineCornerRadius**: `Int`\n  - *standard: 0*\n- **skeletonCornerRadius**: `CGFloat` (IBInspectable)(Macht ihre Skelettansicht mit Ecken)\n  - *standard: 0*\n\nUm diese Standardwerte zu erhalten, kannst du `SkeletonAppearance.default` verwenden. Mit dieser Variable kannst du auch die Werte einstellen:\n\n```swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n> **⚠️ VERALTET!**\n>\n> **useFontLineHeight** wurde abgeschafft. Du kannst stattdessen **textLineHeight** verwenden:\n>\n> ```swift\n> SkeletonAppearance.default.textLineHeight = .relativeToFont\n> ```\n\n### 🎨 Benutzerdefinierte Farben\n\nDu kannst entscheiden, mit welcher Farbe das Skelett eingefärbt wird. Du brauchst nur die gewünschte Farbe oder den gewünschten Farbverlauf als Parameter zu übergeben.\n\n**Verwendung von Volltonfarben**\n\n```swift\nview.showSkeleton(usingColor: UIColor.gray) // Einfarbig\n// oder\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n\n**Verwendung von Farbverläufen**\n\n```swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient) // Farbverlauf\n```\n\nAußerdem bietet **SkeletonView** 20 flache Farben 🤙🏼.\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...```\n\n![](../Assets/flatcolors.png)\n###### Bild von der Website [https://flatuicolors.com](https://flatuicolors.com) entnommen\n\n\n### 🏃‍♀️ Animationen\n\n**SkeletonView** hat zwei eingebaute Animationen, *pulse* für einfarbige Skelette und *sliding* für Farbverläufe.\n\nAußerdem ist es sehr einfach, eine eigene Skelettanimationen zu erstellen.\n\nSkeleton bietet die Funktion `showAnimatedSkeleton`, die eine Closure ```SkeletonLayerAnimation``` besitzt, in der du deine eigene Animation definieren kannst.\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\nDu kannst die Funktion wie folgt aufrufen:\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Passe hier ihre Animation an\n\n  return animation\n}\n```\n\nEs ist ein ```SkeletonAnimationBuilder``` verfügbar. Es ist ein Builder um ```SkeletonLayerAnimation``` zu erstellen.\n\nHeute kann man **Gleitanimationen** für Farbverläufe erstellen, indem man die **Richtung** und die **Dauer** der Animation festlegt (Standard = 1,5s).\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` ist ein enum, mit den folgenden cases:\n\n| Richtung | Vorschau\n|------- | -------\n| .leftRight | ![](../Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](../Assets/sliding_right_to_left.gif)\n| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 TRICK!**\n>\n> Es gibt noch eine andere Möglichkeit, Schiebeanimationen zu erstellen, indem man einfach diese Abkürzung benutzt:\n>\n> ```swift\n> let animation = GradientDirection.leftToRight.slidingAnimation()\n> ```\n\n### 🏄 Übergänge\n\n**SkeletonView** hat eingebaute Übergänge, um die Skelette auf eine *ruhigere* Weise **ein- und auszublenden** 🤙.\n\nUm den Übergang zu benutzen, füge einfach den Parameter ```transition``` zu ihrer Funktion ```showSkeleton()``` oder ```hideSkeleton()``` mit der Übergangszeit hinzu, wie hier:\n\n```swift\nview.showSkeleton(transition: .crossDissolve(0.25))     //Einblenden des Skeleton mit Querauflösen-Übergang mit 0,25 Sekunden Übergangszeit\nview.hideSkeleton(transition: .crossDissolve(0.25))     //Ausblenden des Skeleton mit Querauflösen-Übergang mit 0,25 Sekunden Übergangszeit\n\n```\n\nDer Standardwert ist `crossDissolve(0.25)`\n\n**Vorschau**\n\n<table>\n<tr>\n<td width=\"50%\">\n<center>Keinen</center>\n</td>\n<td width=\"50%\">\n<center>Querauflösen</center>\n</td>\n</tr>\n<tr>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_nofade.gif\"></img>\n</td>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_fade.gif\"></img>\n</td>\n</tr>\n</table>\n\n## ✨ Sonstiges\n\n**Hierarchie**\n\nDa ```SkeletonView``` rekursiv ist, und wir wollen, dass Skeleton sehr effizient ist, wollen wir die Rekursion so schnell wie möglich beenden. Aus diesem Grund musst du die Container-Ansicht auf `Skeletonable` setzen, denn Skeleton wird aufhören, nach `skeletonable` Unteransichten zu suchen, sobald eine Ansicht nicht skelettierbar ist, und damit die Rekursion beenden.\n\nDenn ein Bild sagt mehr als tausend Worte:\n\nIn diesem Beispiel haben wir einen `UIViewController` mit einem `ContainerView` und einem `UITableView`. Wenn der View fertig ist, zeigen wir das Skelett mit dieser Methode:\n\n```\nview.showSkeleton()\n```\n\n> ```isSkeletonable```= ☠️\n\n| Konfiguration | Ergebnis|\n|:-------:|:-------:|\n|<img src=\"../Assets/no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/container_skeletonable_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/all_skeletonables.jpg\" width=\"350\"/>| <img src=\"../Assets/all_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/tableview_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_no_skeletonable_result.png\" height=\"350\"/>|\n|<img src=\"../Assets/tableview_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_skeletonable_result.png\" height=\"350\"/>|\n\n**Skelettansichten-Layout**\n\nManchmal kann es vorkommen, dass das Skelett-Layout nicht zu ihrem Layout passt, weil sich die Grenzen der übergeordneten Ansicht geändert haben. ~Zum Beispiel, wenn du das Gerät drehst.\n\nDu kannst die Skelettansichten wie folgt neu anordnen:\n\n```swift\noverride func viewDidLayoutSubviews() {\n    view.layoutSkeletonIfNeeded()\n}\n```\n\n> 📣 **WICHTIG!**\n>\n> Du solltest diese Methode nicht aufrufen. Ab **Version 1.8.1** brauchst du diese Methode nicht mehr aufzurufen, die Bibliothek macht das automatisch. Du kannst diese Methode also **NUR** in den Fällen verwenden, in denen du das Layout des Skeletts manuell aktualisieren musst.\n\n**Skelett aktualisieren**\n\nDu kannst die Konfiguration des Skeletts jederzeit ändern, wie z.B. seine Farbe, Animation, etc. mit den folgenden Methoden:\n\n```swift\n(1) view.updateSkeleton()                 // Einfarbig\n(2) view.updateGradientSkeleton()         // Farbverlauf\n(3) view.updateAnimatedSkeleton()         // Einfarbig animiert\n(4) view.updateAnimatedGradientSkeleton() // Farbverlauf animiert\n```\n\n**Ausblenden von Ansichten, wenn die Animation beginnt**\n\nManchmal möchte man einige Ansichten ausblenden, wenn die Animation beginnt. Dafür gibt es eine praktische Variable, die man benutzen kann:\n\n```swift\nview.isHiddenWhenSkeletonIsActive = true  // Dies funktioniert nur, wenn isSkeletonable = true\n```\n\n**Benutzerinteraktion nicht ändern, wenn das Skelett aktiv ist**\n\nStandardmäßig ist die Benutzerinteraktion für skelettierte Elemente deaktiviert, aber wenn du den Indikator für die Benutzerinteraktion nicht ändern willst, wenn das Skelett aktiv ist, kannst du die Variable `isUserInteractionDisabledWhenSkeletonIsActive` verwenden:\n\n```swift\nview.isUserInteractionDisabledWhenSkeletonIsActive = false  // Die Ansicht wird aktiv sein, wenn das Skelett aktiv ist.\n```\n\n**Zeilenhöhe der Schriftart für die Skelettlinien in Labels nicht verwenden**\n\n`False`, um die automatische Anpassung des Skeletts an die Schrifthöhe für ein `UILabel` oder `UITextView` zu deaktivieren. Standardmäßig wird die Höhe der Skelettlinien automatisch an die Schrifthöhe angepasst, um den Text im Label-Rect genauer wiederzugeben, anstatt die Bounding Box zu verwenden.\n\n```swift\nlabel.useFontLineHeight = false\n```\n\n**Skelett verzögert anzeigen**\n\nDu kannst die Darstellung des Skeletts verzögern, wenn die Ansichten schnell aktualisiert werden.\n\n```swift\nfunc showSkeleton(usingColor: UIColor,\n                  animated: Bool,\n                  delay: TimeInterval,\n                  transition: SkeletonTransitionStyle)\n```\n\n```swift\nfunc showGradientSkeleton(usingGradient: SkeletonGradient,\n                          animated: Bool,\n                          delay: TimeInterval,\n                          transition: SkeletonTransitionStyle)\n```\n\n**Debug**\n\nUm die Debug-Aufgaben zu erleichtern, wenn etwas nicht richtig funktioniert, hat **`SkeletonView`** einige neue Werkzeuge.\n\nErstens, `UIView` hat eine Variable mit seinen Skelett-Informationen zur Verfügung:\n\n```swift\nvar sk.skeletonTreeDescription: String\n\n```\n\nAußerdem kannst du den neuen **Debug-Modus** aktivieren. Füge einfach die Umgebungsvariable `SKELETON_DEBUG` hinzu um ihn zu aktivieren.\n\n![](../Assets/debug_mode.png)\n\nWenn das Skelett dann erscheint, kannst du die Ansichtshierarchie in der Xcode-Konsole sehen.\n\n```\n{ \n  \"type\" : \"UIView\", // UITableView, UILabel...\n  \"isSkeletonable\" : true,\n  \"reference\" : \"0x000000014751ce30\",\n  \"children\" : [\n    {\n      \"type\" : \"UIView\",\n      \"isSkeletonable\" : true,\n      \"children\" : [ ... ],\n      \"reference\" : \"0x000000014751cfa0\"\n    }\n  ]\n}\n```\n  \n**Unterstützte OS & SDK-Versionen**\n\n- iOS 9.0+\n- tvOS 9.0+\n- Swift 5.3\n\n## ❤️ Beitragen\n\nDies ist ein Open-Source-Projekt, du kannst also gerne dazu beitragen. Wie?\n\n- Eröffne ein [issue](https://github.com/Juanpe/SkeletonView/issues/new).\n- Sende Feedback über [email](mailto://juanpecatalan.com).\n- Schlage deine eigenen Korrekturen und Vorschläge vor und öffne einen Pull Request mit den Änderungen.\n\nSiehe [alle Mitwirkenden](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\nFür weitere Informationen lies bitte die [contributing guidelines](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).\n\n## 📢 Erwähnungen\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)\n- [Best iOS articles, new tools & more](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)\n\n## 🏆 Sponsoren\n\nOpen-Source-Projekte leben nicht lange ohne ihre Hilfe. Wenn du **SkeletonView** nützlich findest, ziehe bitte in Betracht, dieses\nProjekt zu unterstützen, indem du ein Sponsor wirst.\n\nWerde Sponsor über [GitHub Sponsors] (<https://github.com/sponsors/Juanpe>) :heart:\n\n## 👨🏻‍💻 Autor\n\n[Juanpe Catalán](http://www.twitter.com/JuanpeCatalan)\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n## 👮🏻 Lizenz\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "Translations/README_es.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-master\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60\" /></a>\n    <img src=\"http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green\" />\n    <img src=\"https://img.shields.io/badge/platforms-ios%2Btvos-green\" />\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n</p>\n\n<p align=\"center\">\n    <a href=\"#-destacado\">Destacado</a>\n  • <a href=\"#-instalación\">Instalación</a>\n  • <a href=\"#-cómo-funciona\">¿Cómo funciona?</a>\n  • <a href=\"#-miscelánea\">Miscelánea</a>\n  • <a href=\"#️-contribuir\">Contribuir</a>\n</p>\n\n**🌎 README está disponible en estos idiomas: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md) . [🇩🇪](README_de.md)**\n\nHoy en día, La mayoría de las apps tiene procesos asíncronos, como peticiones a una API, procesos que tardan mucho tiempo, etc. Mientras estos procesos se están ejecutando, se suele mostrar un aburrido spinner indicando que algo está pasando.\n\n**SkeletonView** ha sido desarrollada para cubrir esta necesidad, un elegante manera de decirle a los usarios que algo se está procesando y además prepararlos, visualmente, para el contenido que están esperando.\n\nEnjoy it! 🙂\n\n## \n- [](#)\n- [🌟 Destacado](#-destacado)\n- [🎬 Videotutoriales](#-videotutoriales)\n- [📲 Instalación](#-instalación)\n- [🐒 ¿Cómo funciona?](#-cómo-funciona)\n- [](#-1)\n  - [🌿 Colecciones](#-colecciones)\n  - [🔠 Textos](#-textos)\n  - [🦋 Apariencia](#-apariencia)\n  - [🎨 Colores](#-colores)\n        - [Imagen extraída de la web https://flatuicolors.com](#imagen-extraída-de-la-web-httpsflatuicolorscom)\n  - [🏃‍♀️ Animaciones](#️-animaciones)\n  - [🏄 Transiciones](#-transiciones)\n- [✨ Miscelánea](#-miscelánea)\n- [❤️ Contributing](#️-contributing)\n- [📢 Menciones](#-menciones)\n- [👨🏻‍💻 Autor](#-autor)\n- [👮🏻 Licencia](#-licencia)\n\n\n\n## 🌟 Destacado\n\n* Fácil de usar\n* Todas las UIViews son skeletonables\n* Personalizable\n* Universal (iPhone & iPad)\n* Interface Builder friendly\n\n\n## 🎬 Videotutoriales\n\n| [![](https://img.youtube.com/vi/75kgOhWsPNA/maxresdefault.jpg)](https://youtu.be/75kgOhWsPNA)|[![](https://img.youtube.com/vi/MVCiM_VdxVA/maxresdefault.jpg)](https://youtu.be/MVCiM_VdxVA)|[![](https://img.youtube.com/vi/Qq3Evspeea8/maxresdefault.jpg)](https://youtu.be/Qq3Evspeea8)|[![](https://img.youtube.com/vi/ZOoPtBwDRT0/maxresdefault.jpg)](https://youtu.be/ZOoPtBwDRT0)\n|:---:  | :---: |:---:  | :---: \n|[**SkeletonView Guides - Getting started**](https://youtu.be/75kgOhWsPNA)|[**How to Create Loading View with Skeleton View in Swift 5.2**](https://youtu.be/MVCiM_VdxVA)    by iKh4ever Studio|[**Create Skeleton Loading View in App (Swift 5) - Xcode 11, 2020**](https://youtu.be/Qq3Evspeea8)    by iOS Academy| [**Add An Elegant Loading Animation in Swift***](https://youtu.be/ZOoPtBwDRT0)    by Gary Tokman\n\n\n## 📲 Instalación\n\n* [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html):\n\n```ruby\npod 'SkeletonView'\n```\n\n* [Carthage](https://github.com/Carthage/Carthage):\n\n```ruby\ngithub \"Juanpe/SkeletonView\"\n```\n\n* [Swift Package Manager](https://swift.org/package-manager/):\n\n```swift\ndependencies: [\n  .package(url: \"https://github.com/Juanpe/SkeletonView.git\", from: \"1.7.0\")\n]\n```\n\n\n## 🐒 ¿Cómo funciona?\n\nSolo necesitas **3** pasos para usar `SkeletonView`:\n\n1️⃣ Importa SkeletonView en el archivo donde vayas a utilizarlo.\n```swift\nimport SkeletonView\n```\n\n2️⃣ Ahora, debes indicar qué elementos de tu vista son `skeletonables`\n\n**Con código:**\n```swift\navatarImageView.isSkeletonable = true\n```\n**Con IB/Storyboards:**\n\n![](../Assets/storyboard.png)\n\n3️⃣ Una vez indicado, solo tienes que mostrar el **skeleton**. Tienes **4** opciones:\n\n```swift\n(1) view.showSkeleton()                 // Sólido\n(2) view.showGradientSkeleton()         // Degradado\n(3) view.showAnimatedSkeleton()         // Sólido animado\n(4) view.showAnimatedGradientSkeleton() // Degradado animado\n```\n\n**Vista previa**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Sólido</center>\n</td>\n<td width=\"25%\">\n<center>Degradado</center>\n</td>\n<td width=\"25%\">\n<center>Sólido Animado</center>\n</td>\n<td width=\"25%\">\n<center>Degradado Animado</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n\n> 📣 **¡IMPORTANTE!** \n>\n> `SkeletonView` es recursivo. Por lo que si tienes una vsita que contiene varios elementos skeletonables, solo tienes queenecu For example, with `UIViewControllers`.\n\n  \n## \n### 🌿 Colecciones\n\n`SkeletonView` es compatible con `UITableView` and `UICollectionView`.\n\n\n**UITableView**\n\nSi quieres mostrar el skeleton en un `UITableView`, necesitas conformar el protocolo `SkeletonTableViewDataSource`. \n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    // Por defecto: 1\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n\n    // Por defecto:\n    // Calcula cuantas celdas necesita para rellenar todo el frame.\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\nEste protocolo hereda de `UITableViewDataSource`, por lo que puedes reemplazar este protocolo por el protocolo de skeleton sin perder ninguna funcionalidad. El único método que es obligatorio implementar es `cellIdentifierForRowAt`, donde tienes que indicar el identificador de la celda.\n\n**Ejemplo**\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n \nAdemás, tu puedes mostrar el skeleton en las headers y en los footers, conformando el protocolo `SkeletonTableViewDelegate`.\n\n```swift\npublic protocol SkeletonTableViewDelegate: UITableViewDelegate {\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier? // default: nil\n}\n```\n\n> 📣 **¡IMPORTANTE!** \n> \n> 1️⃣ Si estás usando celdas con altura dinámica (**`tableView.rowHeight = UITableViewAutomaticDimension`**), es obligatorio definir el **`estimatedRowHeight`**.\n> \n> 2️⃣ Cuando añades elemetos a una **`UITableViewCell`**, debes añadirlo al **`contentView`** y no a la celda directamente.\n> ```swift\n> cell.contentView.addSubview(titleLabel) ✅         \n> cell.addSubview(titleLabel) ❌\n> ```\n\n  \n\n**UICollectionView**\n\nPara los `UICollectionView`, debes conformar el protocolo `SkeletonCollectionViewDataSource`.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int // Por defecto: 1\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UICollectionView, supplementaryViewIdentifierOfKind: String, at indexPath: IndexPath) -> ReusableCellIdentifier? // Por defecto: nil\n}\n```\n\nEl resto del proceso es exactamente igual que con las `UITableView`.\n\n\n### 🔠 Textos\n\n![](../Assets/multilines2.png)\n\nCuando usas elementos que contienen texto,`SkeletonView` dibujo líneas para simular el texto.\n\nAdemás, puedes decidir el número de líneas. Si  `numberOfLines` es igual a **0**, se calculará automáticamente el número de líneas necesarias para ocupar todo el frame. Sin embargo, si es un número mayor que cero, solo se dibujarán esas líneas.\n\nPuedes especificar algunos atributos para estos elementos:\n\n\n| Atributo | Valores | Por defecto | Vista previa\n| ------- | ------- |------- | -------\n| **Porcentaje de relleno** de la última línea. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)\n| **Radio de las esquinas** de las líneas. | `0...10` | `0` | ![](../Assets/multiline_corner.png)\n\nPara modificar alguno de los valores lo puedes hacer **con código**::\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\nO usando **IB/Storyboards**:\n\n![](../Assets/multiline_customize.png)\n\n\n### 🦋 Apariencia\n\nLos skeletons tiene una apariencia por defecto. Así, cuando no especificas el color, el degradado o las propiedades para las multiíneas, `SkeletonView` usa estos valores.\n\nValores por defecto:\n- **tintColor**: `UIColor`\n    - *default: `.skeletonDefault` (igual que `.clouds` pero se adapta al dark mode)*\n- **gradient**: `SkeletonGradient`\n  - *default: `SkeletonGradient(baseColor: .skeletonDefault)`*\n- **multilineHeight**: `CGFloat`\n  - *default: 15*\n- **multilineSpacing**: `CGFloat`\n  - *default: 10*\n- **multilineLastLineFillPercent**: `Int`\n  - *default: 70*\n- **multilineCornerRadius**: `Int`\n  - *default: 0*\n- **skeletonCornerRadius**: `CGFloat` (IBInspectable)\n  - *default: 0*\n\nPara obtener o modificar estos valores tu puedes usar `SkeletonAppearance.default`:\n```swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n\n### 🎨 Colores\n\nPuedes decidir de qué color se tinta tu skeleton. Solo tienes que indicarlo pasándolo como parámetro:\n\n**Usando colores sólidos**\n```swift\nview.showSkeleton(usingColor: UIColor.gray)\n// o\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n**Usando degradados**\n``` swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient)\n```\n\nAdemás, **SkeletonView** añade 20 colores flat 🤙🏼\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange  ...```\n\n![](../Assets/flatcolors.png)\n###### Imagen extraída de la web [https://flatuicolors.com](https://flatuicolors.com)\n\n\n### 🏃‍♀️ Animaciones\n\n**SkeletonView** tiene pre-definidas dos animaciones, *pulse* para skeleton sólidos y *sliding* para degradados.\n\nAdemás, usando el método `showAnimatedSkeleton`, podemos incluir la `animation` que es de tipo `SkeletonLayerAnimation`, un bloque donde tu puedes crear tus propias animaciones:\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\nTu código quedaría así:\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Personaliza la animación aquí\n\n  return animation\n}\n```\n\n`SkeletonAnimationBuilder` es un builder que permite crear `SkeletonLayerAnimation`.\n\nPor ejemplo, tu puedes crear **sliding animations** para los degradados, decidiendo la **direction** y indicando la **duration** de la animación (default = 1.5s).\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` es un enumerado con estos `cases`:\n\n|  Dirección | Vista previa\n|------- | -------\n| .leftRight | ![](../Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](../Assets/sliding_right_to_left.gif)\n| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 ¡Truco!**\n>\n> Puedes crear una animación sliding, con este shortcut:\n> ```swift\n> let animation = GradientDirection.leftToRight.slidingAnimation()\n> ```\n\n  \n\n### 🏄 Transiciones\n\n**SkeletonView** tiene algunas transiciones listas para usarse cuando **aparece** o se **oculta**. Puedes especificarla así:\n\n```swift\nview.showSkeleton(transition: .crossDissolve(0.25))\nview.hideSkeleton(transition: .crossDissolve(0.25))\n\n```\n\nLa transición por defecto es `crossDissolve(0.25)`\n\n**Vista previa**\n\n<table>\n<tr>\n<td width=\"50%\">\n<center>Sin transición</center>\n</td>\n<td width=\"50%\">\n<center>Cross dissolve</center>\n</td>\n</tr>\n<tr>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_nofade.gif\"></img>\n</td>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_fade.gif\"></img>\n</td>\n</tr>\n</table>\n\n\n## ✨ Miscelánea \n\n  \n\n**Jerarquía**\n\n\n`SkeletonView` es recursivo, pero para que sea eficiente, tenemos que pararar la recursión tan pronto como sea posible. Por este motivo, el contenedor de las vistas debe ser **`skeletonable`**, porque `SkeletonView` parará de buscar vistas skeletonables cuando encuentre una que no lo sea, dentro de la jerarquía.\n\nComo una imagen vale más que mil palabras:\n\nEn este ejemplo, tenemos un `UIViewController` con un `containerView` y una `UITableView`. Cuando la vista está lista, para mostrar el skeleton ejecutamos el método: \n```\nview.showSkeleton()\n```\n\n> `isSkeletonable`= ☠️\n\n| Configuración | Resultado|\n|:-------:|:-------:|\n|<img src=\"../Assets/no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/container_skeletonable_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/all_skeletonables.jpg\" width=\"350\"/>| <img src=\"../Assets/all_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/tableview_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_no_skeletonable_result.png\" height=\"350\"/>|\n|<img src=\"../Assets/tableview_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_skeletonable_result.png\" height=\"350\"/>|\n\n  \n\n**Jerarquía en las colecciones**\n\nEsta ilustración muestra como deberías específicar qué elementos son skeletonables cuando estás usando una `UITableView`:\n\n<img src=\"../Assets/tableview_scheme.png\" width=\"700px\">\n\n\n**Actualiza el skeleton**\n\nPuedes cambiar la configuración del skeleton, como el color, la animación, etc, con los siguientes métodos:\n\n```swift\n(1) view.updateSkeleton()                 // Sólido\n(2) view.updateGradientSkeleton()         // Degradado\n(3) view.updateAnimatedSkeleton()         // Sólido animado\n(4) view.updateAnimatedGradientSkeleton() // Degradado animado\n```\n\n\n**Debug**\n\nPara facilitar las tareas de debug cuando algo no está funcionando bien, **`SkeletonView`** tiene una nueva herramienta.\n\nPrimero, `UIView` tiene una nueva propiedad que contiene toda la info del skeleton:\n```swift\nvar skeletonDescription: String\n\n```\nY es representada de la siguiente manera:\n\n![](../Assets/debug_description.png)\n\nPara activar el **modo debug**. Solo tienes que añadir una variable de entorno con esta clave `SKELETON_DEBUG` y activarla.\n\n![](../Assets/debug_mode.png)\n\nEntonces, cuando el skeleton aparece, tu podrás ver la jerarquía de vistas en la consola de Xcode.\n\n<details>\n<summary>Abre para ver un ejemplo </summary>\n<img src=\"../Assets/hierarchy_output.png\" />\n</details>\n\n  \n  **OS Soportado & Versiones SDK**\n\n* iOS 9.0+\n* tvOS 9.0+\n* Swift 5\n\n\n## ❤️ Contributing\n\nEsto es un proyecto open source, siéntete libre de contribuir. ¿Cómo?\n- Abre un [issue](https://github.com/Juanpe/SkeletonView/issues/new).\n- Envía feedback a través del [email](mailto://juanpecatalan.com).\n- Propone tus propies fixes, sugerencias y abre una Pull Request con los cambios.\n\nÉchale un vistazo a [los que ya han contribuído](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\nPara más información, por favor, lee la [guía de contribución](https://github.com/Juanpe/SkeletonView/blob/main/CONTRIBUTING.md).\n\n\n## 📢 Menciones\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)\n- [Best iOS articles, new tools & more](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)\n\n\n\n## 👨🏻‍💻 Autor\n\n[Juanpe Catalán](http://www.twitter.com/JuanpeCatalan)\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n\n## 👮🏻 Licencia\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "Translations/README_fr.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-master\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60\" /></a>\n    <img src=\"https://img.shields.io/badge/Swift-5-orange.svg\" />\n    <img src=\"http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green\" />\n    <img src=\"https://img.shields.io/badge/platforms-ios%2Btvos-green\" />\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n    <br/>\n    <a href=\"https://twitter.com/JuanpeCatalan\">\n        <img src=\"https://img.shields.io/badge/contact-@JuanpeCatalan-blue.svg?style=flat\" alt=\"Twitter: @JuanpeCatalan\" />\n    </a>\n    <a href=\"https://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge\">\n        <img src=\"https://badges.gitter.im/SkeletonView/community.svg?style=flat\" />\n    </a>\n    <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MJ4Y2D9DEX6FL&lc=ES&item_name=SkeletonView&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted\">\n        <img src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"PayPal\" />\n    <a href=\"https://twitter.com/intent/tweet?text=Wow%20This%20library%20is%20awesome:&url=https%3A%2F%2Fgithub.com%2FJuanpe%2FSkeletonView\">\n      <img src=\"https://img.shields.io/twitter/url/https/github.com/Juanpe/SkeletonView.svg?style=social\" alt=\"Licence\" />\n    </a>\n</p>\n\n\n**🌎 Traductions: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md) . [🇩🇪](README_de.md)**\n\nAujourd'hui, presque toutes les applications ont des processus asynchrones, tels que les requêtes Api, les processus de longue durée, etc. Et pendant que les processus fonctionnent, les développeurs affichent généralement une vue de chargement pour montrer aux utilisateurs que quelque chose se passe.\n\n\"SkeletonView\" a été créé pour répondre à ce besoin, une manière élégante de montrer aux utilisateurs que quelque chose se passe et aussi de les préparer aux contenus qu'ils attendent.\n\nProfitez-en! 🙂\n\n- [🌟 Caractéristiques](#-caractéristiques)\n- [🎬 Guides](#-guides)\n- [📲 Installation](#-installation)\n    - [Utilisation de CocoaPods](#utilisation-de-cocoapods)\n    - [Utilisation de Carthage](#utilisation-de-carthage)\n    - [Utilisation du gestionnaire de paquets Swift](#utilisation-du-gestionnaire-de-paquets-swift)\n- [🐒 Mode d'emploi](#-mode-demploi)\n  - [Extra](#extra)\n    - [Mise en page des vues squelettes](#mise-en-page-des-vues-squelettes)\n    - [Mise à jour de la configuration du squelette](#mise-à-jour-de-la-configuration-du-squelette)\n  - [🌿 Collections](#-collections)\n    - [UITableView](#uitableview)\n    - [UICollectionView](#uicollectionview)\n  - [📰 Texte multiligne](#-texte-multiligne)\n      - [🎛 Personnaliser](#-personnaliser)\n  - [🎨 Couleurs personnalisées](#-couleurs-personnalisées)\n        - [Image tirée du site web https://flatuicolors.com](#image-tirée-du-site-web-httpsflatuicolorscom)\n  - [🦋 Présentation](#-présentation)\n  - [🤓 Animations personnalisées](#-animations-personnalisées)\n  - [🏄 Transitions](#-transitions)\n  - [👨👧👦 Hiérarchie](#-hiérarchie)\n  - [🔬 Débugger](#-débugger)\n  - [📚 Documentation](#-documentation)\n  - [📋 Versions OS et SDK supportées](#-versions-os-et-sdk-supportées)\n- [📬 Prochaines étapes](#-prochaines-étapes)\n- [❤️ Contribuer](#️-contribuer)\n        - [Projet généré avec SwiftPlate](#projet-généré-avec-swiftplate)\n- [📢 Mentions](#-mentions)\n- [👨🏻‍💻 Auteur](#-auteur)\n- [👮🏻 Licence](#-licence)\n\n## 🌟 Caractéristiques\n\n- [x] Facile à utiliser\n- [x] Tous les UIViews sont squelettisables\n- [x] Entièrement personnalisable\n- [x] Universel (iPhone et iPad)\n- [x] Interface Builder friendly\n- [x] Syntaxe Swift simple\n- [x] Base de code légère et lisible\n\n## 🎬 Guides\n\n [<img src=\"../Assets/thumb_getting_started.png\">](https://youtu.be/75kgOhWsPNA)\n\n## 📲 Installation\n\n#### Utilisation de [CocoaPods](https://cocoapods.org)\n\nEditez votre \"podfile\" et spécifiez la dépendance:\n\n```ruby\npod \"SkeletonView\"\n```\n\n#### Utilisation de [Carthage](https://github.com/carthage)\n\nModifiez votre \"Cartfile\" et spécifiez la dépendance:\n\n```bash\ngithub \"Juanpe/SkeletonView\"\n```\n\n#### Utilisation du [gestionnaire de paquets Swift](https://github.com/apple/swift-package-manager)\n\nUne fois que vous avez configuré votre paquet Swift, ajouter `SkeletonView` comme dépendance est aussi facile que de l'ajouter à la valeur des `dépendances` de votre `Package.swift`.\n\n```swift\n  dependencies: [\n    .package(url: \"https://github.com/Juanpe/SkeletonView.git\", from: \"1.7.0\")\n  ]\n```\n\n## 🐒 Mode d'emploi\n\nSeulement **3** étapes nécessaires pour utiliser `SkeletonView` :\n\n**1.** Importer SkeletonView au bon endroit.\n```swift\nimport SkeletonView\n```\n\n**2.** Maintenant, définissez les vues qui seront `squelettisables`. Vous y arrivez de deux façons :\n\n**En utilisant du code:**\n```swift\navatarImageView.isSkeletonable = true\n```\n**Utilisation des IB/Storyboards:**\n\n![](../Assets/storyboard.png)\n\n**Une fois que vous avez défini les vues, vous pouvez montrer le **squelette**. Pour le faire, vous avez quatre choix :\n\n```swift\n(1) view.showSkeleton() // Solide\n(2) view.showGradientSkeleton() // Gradient\n(3) view.showAnimatedSkeleton() // Solide animé\n(4) view.showAnimatedGradientSkeleton() // Gradient animé\n```\n\n**Preview**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Solide</center>\n</td>\n<td width=\"25%\">\n<center>Gradient</center>\n</td>\n<td width=\"25%\">\n<center>Animé Solide</center>\n</td>\n<td width=\"25%\">\n<center>Animé Gradient</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n> **IMPORTANT!**\n>>```SkeletonView``` est récursif, donc si vous voulez montrer le squelette dans toutes les vues squelettables, il vous suffit d'appeler la méthode `show` dans la vue principale du conteneur. Par exemple, avec UIViewControllers\n\n### Extra\n\n#### Mise en page des vues squelettes\n\nIl arrive que le squelette ne corresponde pas à votre mise en page parce que les limites de la vue parent ont changé. ~Par exemple, la rotation de l'appareil.~\n\nVous pouvez relayer les vues du squelette de cette manière :\n\n```swift\noverride func viewDidLayoutSubviews() {\n    view.layoutSkeletonIfNeeded()\n}\n```\n\n⚠️⚠️ Vous ne devriez pas appeler cette méthode. À partir de la *version 1.8.1*, vous n'avez pas besoin d'appeler cette méthode, la bibliothèque le fait automatiquement. Vous pouvez donc utiliser cette méthode *seulement* dans les cas où vous devez mettre à jour manuellement la présentation du squelette.\n\n#### Mise à jour de la configuration du squelette\n\nVous pouvez modifier la configuration du squelette à tout moment comme sa couleur, son animation, etc :\n\n```swift\n(1) view.updateSkeleton() // Solide\n(2) view.updateGradientSkeleton() // Gradient\n(3) view.updateAnimatedSkeleton() // Solid animated\n(4) view.updateAnimatedGradientSkeleton() // Gradient animé\n```\n\n### 🌿 Collections\n\n Maintenant, `SkeletonView` est compatible avec `UITableView` et `UICollectionView`.\n\n#### UITableView\n\nSi vous voulez montrer le squelette dans un `UITableView`, vous devez vous conformer au protocole `SkeletonTableViewDataSource`.\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier?\n    func collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier?\n}\n```\n\nComme vous pouvez le voir, ce protocole hérite de `UITableViewDataSource`, vous pouvez donc remplacer ce protocole par le protocole squelette.\n\nCe protocole a une implémentation par défaut:\n\n``` swift\nfunc numSections(in collectionSkeletonView: UITableView) -> Int\n// Par défaut: 1\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// Par défaut:\n// Il calcule le nombre de cellules nécessaires pour remplir l'ensemble du tableau\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, identifierForHeaderInSection section: Int) -> ReusableHeaderFooterIdentifier?\n// Par défaut: nil\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, identifierForFooterInSection section: Int) -> ReusableHeaderFooterIdentifier?\n// Par défaut: nil\n```\n\nIl n'y a qu'une seule méthode à mettre en œuvre pour faire connaître au Squelette l'identifiant de la cellule. Cette méthode n'a pas d'implémentation par défaut :\n``` swift\n func collectionSkeletonView(_ skeletonView : UITableView, cellIdentifierForRowAt indexPath : IndexPath) -> ReusableCellIdentifier\n```\n\n**Exemple**\n``` swift\n func collectionSkeletonView(_ skeletonView : UITableView, cellIdentifierForRowAt indexPath : IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\".\n}\n ```\n\n> **IMPORTANT!**\n> Si vous utilisez des cellules redimensionnables (`tableView.rowHeight = UITableViewAutomaticDimension` ), il est obligatoire de définir la `estimatedRowHeight`.\n\n👩🏼 **Comment préciser quels éléments sont squelettisables ?\n\nVoici une illustration qui montre comment vous devez spécifier quels éléments sont squelettisables lorsque vous utilisez une `UITableView` :\n\n![](../Assets/tableview_scheme.png)\n\nComme vous pouvez le voir, nous devons faire `skeletonable` la tableview, la cellule et les éléments de l'interface visuelle, mais nous n'avons pas besoin de faire `skeletonable` le `contentView`.\n\n#### UICollectionView\n\nPour ```UICollectionView```, vous devez conformer le protocole `SkeletonCollectionViewDataSource`.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\nLe reste du processus ressemble à une `UITableView`.\n\n### 📰 Texte multiligne\n\n![](../Assets/multilines2.png)\n\nLorsqu'on utilise des éléments avec du texte, `SkeletonView` dessine des lignes pour simuler le texte.\nEn outre, vous pouvez décider combien de lignes vous voulez. Si `numberOfLines` est réglé à zéro, il calculera le combien de lignes sont nécessaires pour remplir tout le squelette et il sera dessiné. Au contraire, si vous le réglez sur un, deux ou tout autre nombre supérieur à zéro, il ne dessinera que ce nombre de lignes.\n\n##### 🎛 Personnaliser\n\nVous pouvez définir certaines propriétés pour les éléments multilignes.\n\n| Propriété | Valeurs | Par défaut | Aperçu\n| ------- | ------- |------- | -------\n| **Pourcentage de remplissage** de la dernière ligne. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)\n| **Corner radius** des lignes. (**NEW**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)\n\n\nPour modifier le pourcentage ou le rayon **à l'aide du code**, définissez les propriétés :\n``` swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\nOu, si vous préférez, utilisez l'**IB/Storyboard** :\n\n![](../Assets/multiline_customize.png)\n\n### 🎨 Couleurs personnalisées\n\nVous pouvez décider la couleur du squelette. Il vous suffit de passer comme paramètre la couleur ou le gradient que vous souhaitez.\n\n**Utiliser des couleurs solides**\n``` swift\nview.showSkeleton(usingColor : UIColor.gray) // Solide\n// ou\nview.showSkeleton(usingColor : UIColor(red : 25.0, green : 30.0, blue : 255.0, alpha : 1.0))\n```\n**Utilisation des gradients**\n``` swift\nlet gradient = SkeletonGradient(baseColor : UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient : gradient) // Gradient\n```\n\nEn outre, `SkeletonView` dispose de 20 couleurs unies 🤙🏼\n\n`UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange ...`\n\n![](../Assets/flatcolors.png)\n###### Image tirée du site web [https://flatuicolors.com](https://flatuicolors.com)\n\n### 🦋 Présentation\n\n**NOUVEAU** Les squelettes ont une apparence par défaut. Ainsi, lorsque vous ne spécifiez pas la couleur, le gradient ou les propriétés multilignes, `SkeletonView` utilise les valeurs par défaut.\n\nValeurs par défaut :\n- **tintColor** : UIColor\n    - *défaut : `.skeletonDefault` (comme `.clouds` mais adaptable au thème sombre)*\n- **gradient** : SkeletonGradient\n  - *défaut : `SkeletonGradient(baseColor : .skeletonDefault)`*\n- **multilineHeight** : CGFloat\n  - *défaut : 15*\n- **multilineSpacing** : CGFloat\n  - *défaut : 10*\n- **multilineLastLineFillPercent** : Int\n  - *défaut : 70*\n- **multilineCornerRadius** : Int\n  - *défaut : 0*\n- **skeletonCornerRadius** : CGFloat (IBInspectable) (Faites votre vue squelette avec des coins)\n  - *défaut : 0*\n\nPour obtenir ces valeurs par défaut, vous pouvez utiliser `SkeletonAppearance.default`. En utilisant cette propriété, vous pouvez également définir les valeurs :\n``` swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n### 🤓 Animations personnalisées\n\n`SkeletonView` a deux animations intégrées, *pulse* pour les squelettes solides et *sliding* pour les gradients.\n\nDe plus, si vous voulez faire votre propre animation de squelette, c'est très facile.\n\nSkeleton fournit la fonction `showAnimatedSkeleton` qui possède une fermeture `SkeletonLayerAnimation` où vous pouvez définir votre animation personnalisée.\n\n``` swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\nVous pouvez appeler la fonction comme ceci :\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Personnalisez ici votre animation\n\n  return animation\n}\n```\n\n`SkeletonAnimationBuilder` est disponible. C'est un constructeur pour faire `SkeletonLayerAnimation`.\n\nAujourd'hui, vous pouvez créer des **animations glissantes** pour les gradients, en décidant de la **direction** et en fixant la **durée** de l'animation (par défaut = 1,5s).\n\n```swift\n// func makeSlidingAnimation(withDirection direction : GradientDirection, duration : CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection : .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient : gradient, animation : animation)\n\n```\n\n`GradientDirection` est une `enum`, avec ces cas :\n\n| Direction | Aperçu\n|------- | -------\n| .leftRight | ![](../Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](../Assets/sliding_right_to_left.gif)\n| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 TRICK!**\nIl existe une autre façon de créer des animations de glissement, en utilisant simplement ce raccourci :\n>>```let animation = GradientDirection.leftToRight.slidingAnimation()```\n\n### 🏄 Transitions\n\n`SkeletonView` a des transitions intégrées pour **montrer** ou **cacher** les squelettes d'une manière *lisse* 🤙\n\nPour utiliser la transition, il suffit d'ajouter le paramètre \"transition\" à votre fonction `showSkeleton()` ou `hideSkeleton()` avec le temps de transition, comme ceci :\n\n```swift\nview.showSkeleton(transition : .crossDissolve(0.25))     //Montrer la transition de dissolution croisée du squelette avec un temps de fondu de 0,25 seconde\nview.hideSkeleton(transition : .crossDissolve(0.25))     //Cachez la transition de dissolution croisée du squelette avec un temps de fondu de 0,25 seconde\n```\n\nLa valeur par défaut est `crossDissolve(0.25)`.\n\n**Preview**\n\n<table>\n<tr>\n<td width=\"50%\">\n<center>None</center>\n</td>\n<td width=\"50%\">\n<center>Cross dissolve</center>\n</td>\n</tr>\n<tr>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_nofade.gif\"></img>\n</td>\n<td width=\"50%\">\n<img src=\"../Assets/skeleton_transition_fade.gif\"></img>\n</td>\n</tr>\n</table>\n\n### 👨👧👦 Hiérarchie\n\nPuisque `SkeletonView` est récursif, et que nous voulons que le squelette soit très efficace, nous voulons arrêter la récursivité dès que possible. Pour cette raison, vous devez définir la vue du conteneur comme `Skeletonable`, parce que Skeleton arrêtera de chercher des sous-vues `squelettisables` dès qu'une vue n'est pas `Skeletonable`, cassant alors la récursivité.\n\nParce qu'une image vaut mille mots :\n\nDans cet exemple, nous avons un `UIViewController` avec une `ContainerView` et une `UITableView`. Lorsque la vue est prête, nous montrons le squelette en utilisant cette méthode :\n```\nview.showSkeleton()\n```\n\n> ```isSkeletonable```= ☠️\n\n| Configuration | Résultat|\n|:-------:|:-------:|\n|<img src=\"../Assets/no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/no_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/container_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/container_skeletonable_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/all_skeletonables.jpg\" width=\"350\"/>| <img src=\"../Assets/all_skeletonables_result.png\" width=\"350\"/>|\n|<img src=\"../Assets/tableview_no_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_no_skeletonable_result.png\" height=\"350\"/>|\n|<img src=\"../Assets/tableview_skeletonable.jpg\" width=\"350\"/> | <img src=\"../Assets/tableview_skeletonable_result.png\" height=\"350\"/>|\n\n### 🔬 Débugger\n\n**NOUVEAU** Afin de faciliter les tâches de debuggage lorsque quelque chose ne fonctionne pas bien. `SkeletonView` a de nouveaux outils.\n\nTout d'abord, `UIView` a une nouvelle propriété disponible avec son squelette d'information :\n```swift\nvar skeletonDescription : String\n```\nLa représentation du squelette ressemble à ceci :\n\n![](../Assets/debug_description.png)\n\nEn outre, vous pouvez activer le nouveau mode **debug**. Il suffit d'ajouter la variable d'environnement `SKELETON_DEBUG` et de l'activer.\n\n![](../Assets/debug_mode.png)\n\nEnsuite, lorsque le squelette apparaît, vous pouvez voir la hiérarchie des vues dans la console Xcode.\n\n<details>\n<summary>Ouvrez pour voir un exemple de sortie</summary>\n<img src=\"../Assets/hierarchy_output.png\" />\n</details>\n\n### 📚 Documentation\nBientôt disponible...😅\n\n### 📋 Versions OS et SDK supportées\n\n* iOS 9.0+\n* tvOS 9.0+\n* Swift 5\n\n## 📬 Prochaines étapes\n\n* [x] Fixer le pourcentage de remplissage de la dernière ligne dans les éléments multilignes\n* [x] Ajout d'autres animations en dégradé\n* [x] Cellules redimensionnables prises en charge\n* [x] Compatible avec CollectionView\n* [x] Compatible avec tvOS\n* [x] Ajouter l'état de recouvrement\n* [x] Apparence personnalisée par défaut\n* [x] Mode de debuggage\n* [x] Ajouter des animations lorsqu'il montre/cache les squelettes\n* [ ] Compatible avec les collections personnalisées\n* [ ] Compatible avec MacOS et WatchOS\n\n## ❤️ Contribuer\nIl s'agit d'un projet open source, alors n'hésitez pas à y contribuer. Comment ?\n- Ouvrez un [numéro](https://github.com/Juanpe/SkeletonView/issues/new).\n- Envoyez vos commentaires via [email](mailto://juanpecatalan.com).\n- Proposez vos propres correctifs, suggestions et ouvrez une `pull request` avec les changements.\n\nVoir [tous les contributeurs](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\n###### Projet généré avec [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)\n\n## 📢 Mentions\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles] (https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 articles Swift de novembre] (https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 bibliothèques incroyables pour iOS Swift (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Bulletin d'information sur les développements Swift #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Bulletin d'information Génial iOS #74](https://ios.libhunt.com/newsletter/74)\n- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)\n- [Meilleurs articles sur iOS, nouveaux outils et plus](https://medium.com/flawless-app-stories/best-ios-articles-new-tools-more-fcbe673e10d)\n\n## 👨🏻‍💻 Auteur\n[1.1]: http://i.imgur.com/tXSoThF.png\n[1]: http://www.twitter.com/JuanpeCatalan\n\n* Juanpe Catalán [![alt text][1.1]][1]\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n## 👮🏻 Licence\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "Translations/README_ko.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-master\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60\" /></a>\n    <img src=\"https://img.shields.io/badge/Swift-5-orange.svg\" />\n    <img src=\"http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green\" />\n    <img src=\"https://img.shields.io/badge/platforms-ios%2Btvos-green\" />\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n    <br/>\n    <a href=\"https://twitter.com/JuanpeCatalan\">\n        <img src=\"https://img.shields.io/badge/contact-@JuanpeCatalan-blue.svg?style=flat\" alt=\"Twitter: @JuanpeCatalan\" />\n    </a>\n    <a href=\"https://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge\">\n        <img src=\"https://badges.gitter.im/SkeletonView/community.svg?style=flat\" />\n    </a>\n    <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MJ4Y2D9DEX6FL&lc=ES&item_name=SkeletonView&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted\">\n        <img src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"PayPal\" />\n    <a href=\"https://twitter.com/intent/tweet?text=Wow%20This%20library%20is%20awesome:&url=https%3A%2F%2Fgithub.com%2FJuanpe%2FSkeletonView\">\n      <img src=\"https://img.shields.io/twitter/url/https/github.com/Juanpe/SkeletonView.svg?style=social\" alt=\"License\" />\n    </a>\n</p>\n\n**🌎 번역에 도움을 주신분들: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md) . [🇩🇪](README_de.md)**\n\n오늘날 거의 대부분의 앱들은 비동기 방식의 API 호출을 사용하는 프로세스를 가지고 있습니다.\n프로세스가 작동하는동안 개발자들은 작업이 실행되고 있다는것을 사용자들에게 보여주기 위해서 로딩 뷰를 배치합니다.\n\n```SkeletonView```는 이러한 필요에 의해 고안되었고, 사용자들에게 무엇인가 로딩이 되고 있다는것을 보여주면서 기다리는 콘텐츠에 대해서도 미리 준비할 수 있게 해주는 우아하게 표현할수 있는 방법입니다\n\n맘껏 누리세요 🙂\n\n* [기능](#-features)\n* [가이드](#-guides)\n* [설치방법](#-installation)\n  * [Cocoapods](#using-cocoapods)\n  * [Carthage](#using-carthage)\n  * [SPM](#using-swift-package-manager)\n* [어떻게 사용하나요?](#-how-to-use)\n  * [Collections](#-collections)\n  * [Multiline text](#-multiline-text)\n  * [Custom colors](#-custom-colors)\n  * [Appearance](#-appearance)\n  * [Custom animations](#-custom-animations)\n  * [Hierarchy](#-hierarchy)\n  * [Debug](#-debug)\n* [문서화](#-documentation)\n* [지원되는 OS와 SDK 버전](#-supported-os--sdk-versions)\n* [Next steps](#-next-steps)\n* [Contributing](#-contributing)\n* [Mentions](#-mentions)\n* [개발자](#-author)\n* [라이센스](#-license)\n\n\n## 🌟 기능\n\n- [x] 사용이 쉽습니다\n- [x] 모든 `UIView`에서 사용가능합니다\n- [x] 전체 커스터마이징이 가능합니다\n- [x] 공통으로 이용가능합니다 (iPhone & iPad)\n- [x] `Interface Builder` 에서 사용 가능합니다.\n- [x] 간단한 스위프트 문법\n- [x] 가볍고 가독성 좋은 코드\n\n## 🎬 사용가이드\n\n [<img src=\"../Assets/thumb_getting_started.png\">](https://youtu.be/75kgOhWsPNA)\n\n## 📲 설치 방법\n\n#### [CocoaPods](https://cocoapods.org) 로 사용하기\n\n당신의 프로젝트 `Podfile` 파일에 아래와 같이 입력합니다:\n\n```ruby\npod \"SkeletonView\"\n```\n\n#### [Carthage](https://github.com/carthage)로 사용하기\n\n당신의 프로젝트 `Cartfile` 파일에 아래와 같이 입력합니다:\n\n```bash\ngithub \"Juanpe/SkeletonView\"\n```\n\n#### [Swift Package Manager](https://github.com/apple/swift-package-manager)로 사용하기\n\n\n당신의 프로젝트에 Swift package를 설정한다면, `SkeletonView` 를 `Package.swift` 파일에 있는 `dependencies`에 추가하시면 됩니다.\n\n\n```swift\n  dependencies: [\n    .package(url: \"https://github.com/Juanpe/SkeletonView.git\", from: \"1.6\")\n  ]\n```\n\n\n\n## 🐒 어떻게 사용하나요?\n\n`SkeletonView` 를 이용하기 위해서는 딱 **3** 단계만 기억하세요:\n\n**1.** 사용하고자 하는 파일에서 `SkeletonView` 를 `Import` 합니다.\n```swift\nimport SkeletonView\n```\n\n**2.** 자, 그렇다면 UIView 속성에  `skeletonables` 를 이용하실 수 있습니다. 두가지 옵션이 있습니다\n\n**코드로 사용하는 방법:**\n```swift\navatarImageView.isSkeletonable = true\n```\n**인터페이스빌더 / 스토리보드를 이용하는 방법:**\n\n![](../Assets/storyboard.png)\n\n**3.** 당신이 뷰를 세팅할때, **skeleton** 옵션을 사용 할 수 있습니다. 총 **4** 가지 옵션을 지원합니다:\n\n```swift\n(1) view.showSkeleton()                 // Solid\n(2) view.showGradientSkeleton()         // Gradient\n(3) view.showAnimatedSkeleton()         // Solid animated\n(4) view.showAnimatedGradientSkeleton() // Gradient animated\n```\n\n**미리보기**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Solid</center>\n</td>\n<td width=\"25%\">\n<center>Gradient</center>\n</td>\n<td width=\"25%\">\n<center>Solid Animated</center>\n</td>\n<td width=\"25%\">\n<center>Gradient Animated</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n> **중요!**\n>>```SkeletonView``` 는 재귀적으로 되어있습니다, 만약 모든 뷰에 대해서 skeleton을 호출하고 싶다면, 메인 컨테이너 뷰에서 show `method`를 호출하여야 합니다. 예를 들자면 UIViewControllers가 있습니다.\n\n\n\n### 🌿 Collections\n\n 현재, ```SkeletonView``` 는  ```UITableView``` 와 ```UICollectionView```에서 호환됩니다.\n\n#### UITableView\n\n만약 ```UITableView```에서 skeleton을 호출하고 싶다면, ```SkeletonTableViewDataSource``` protocol 을 구현하여야 합니다.\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\n해당 프로토클은 보시다시피  ```UITableViewDataSource```를 상속받아 구현하였으므로, skeleton의 protocol과 대체 가능합니다.\n\n프로토콜의 기본 구현은 다음과 같습니다:\n\n``` swift\nfunc numSections(in collectionSkeletonView: UITableView) -> Int\n// Default: 1\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// Default:\n// 전체 테이블 뷰를 채우는데 필요한 셀 수를 계산합니다\n```\n\n해당 메소드는 당신이 구현하여야할 cell identifier을 아는 경우에만 사용합니다, 해당 메소드는 기본으로 구현하지 않아도됩니다 :\n\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n ```\n\n**Example**\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n\n> **중요!**\n> 만약 사이즈가 변하는 셀을 사용한다면 (`tableView.rowHeight = UITableViewAutomaticDimension` ),`estimatedRowHeight`를 무조건 정의해주세요.\n\n\n👩🏼‍🏫  **어떻게 특정 요소에 skeleton 을 지정할까요?**\n\n아래의 그림은 `UITableView` 에서 특정한 요소에 skeleton 을 지정하는 방법을 보여주는 이미지 입니다:\n\n![](../Assets/tableview_scheme.png)\n\n위의 이미지에서 보이듯, 테이블 뷰와 셀에 들어가는 UI 요소들에는 적용을 해야하지만, `contentView`에 skeleton을 적용할 필요는 없습니다.\n\n####  UICollectionView\n\n ```UICollectionView``` 에 적용을 하기 위해서는, ```SkeletonCollectionViewDataSource``` protocol 을 구현할 필요가 있습니다.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\n```UITableView``` 와 사용방법은 같습니다.\n\n### 📰 Multiline text\n\n\n![](../Assets/multilines2.png)\n\n텍스트가 들어있는 요소를 사용한다면, ```SkeletonView``` 에서 텍스트의 라인을 그려줍니다.\n그리고, 원하는 라인 수를 설정할 수 있습니다. 만약   ```numberOfLines``` 을 0으로 설정한다면, 자동으로 필요한 라인수를 계산해서 그려줍니다. 대신 값이 설정되어있다면 설정된 수만큼의 라인이 그려집니다.\n\n##### 🎛 Customize\n\n당신은 멀티라인을 위해 몇가지 옵션을 설정할 수 있습니다.\n\n\n| 속성                                              | 값         | 기본값   | 미리보기                               |\n| ----------------------------------------------- | --------- | ----- | ---------------------------------- |\n| 마지막 라인의 **퍼센트** 를 지정 할 수 있습니다.                  | `0...100` | `70%` | ![](../Assets/multiline_lastline.png) |\n| 라인의 **Corner radius** 를 지정할 수 있습니다. (**새로운기능**) | `0...10`  | `0`   | ![](../Assets/multiline_corner.png)   |\n\n\n\n라인의 radius를 지정하기 위해서는  **코드** 를 이용합니다, 아래 처럼 코드를 작성합니다:\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\n혹은 **IB/Storyboard** 를 이용하실 수 있습니다:\n\n![](../Assets/multiline_customize.png)\n\n### 🎨 Custom colors\n\n당신은 skeleton의 색상을 지정 할 수 있습니다. 간단하게 원하는 색상을 파라미터로 넘겨주시면 됩니다.\n\n**단색 이용방법**\n``` swift\nview.showSkeleton(usingColor: UIColor.gray) // Solid\n// or\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n**그라디언트 이용 방법**\n``` swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient) // Gradient\n```\n\n게다가, ```SkeletonView``` 에서는 20가지의 기본 컬러를 지원합니다 🤙🏼\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange  ...```\n\n![](../Assets/flatcolors.png)\n###### 위 이미지는 [https://flatuicolors.com](https://flatuicolors.com) 사이트에서 발췌했습니다.\n\n### 🦋 Appearance\n\n**새로운 사항** skeleton 은  기본설정 값이 정해져 있습니다. 만약 커스텀 컬러를 사용할 필요가 없다면, `SkeletonView` 에 지정 되어있는 기본설정을 사용하시면 됩니다.\n\n기본 설정값:\n- **tintColor**: UIColor\n    - *기본값: .clouds*\n- **gradient**: SkeletonGradient\n  - *기본값: SkeletonGradient(baseColor: .clouds)*\n- **multilineHeight**: CGFloat\n  - *기본값: 15*\n- **multilineSpacing**: CGFloat\n  - *기본값: 10*\n- **multilineLastLineFillPercent**: Int\n  - *기본값: 70*\n- **multilineCornerRadius**: Int\n  - *기본값: 0*\n\n`SkeletonAppearance.default` 에는 사용 되어지는 기본 값들이 설정되어 있습니다 . 아래의 코드와 같이 사용할 수 있습니다:\n```Swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n\n### 🤓 커스텀 애니메이션\n\n```SkeletonView``` 에는 두가지 애니메이션이 내장되어 있습니다, 단색 *바운스* 애니메이션과  그라디언트 *슬라이드* 애니메이션 입니다 .\n\n게다가, 직접 애니메이션을 추가하고 싶다면 정말 간단합니다.\n\n\nSkeleton 에서는 `showAnimatedSkeleton` 함수를  ```SkeletonLayerAnimation```에 정의하여 맞춤형 애니메이션을 정의할 수 있도록 되어 있습니다.\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\n함수는 이렇게 호출 가능합니다:\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Customize here your animation\n\n  return animation\n}\n```\n\n```SkeletonAnimationBuilder```의 사용이 가능합니다. ```SkeletonLayerAnimation```을 만들기 위해 사용됩니다.\n\n이제, 그라디언트를 위한 **슬라이딩 애니메이션** 을 만들 수 있습니다, 애니메이션을 위한  **방향** 과  **지속시간** 을 설정 할 수 있습니다.  (기본값 = 1.5초).\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` 는 enum 으로 정의 되어있습니다., 아래의 케이스를 참조하세요:\n\n| 방향                  | 미리보기                                           |\n| ------------------- | ---------------------------------------------- |\n| .leftRight          | ![](../Assets/sliding_left_to_right.gif)          |\n| .rightLeft          | ![](../Assets/sliding_right_to_left.gif)          |\n| .topBottom          | ![](../Assets/sliding_top_to_bottom.gif)          |\n| .bottomTop          | ![](../Assets/sliding_bottom_to_top.gif)          |\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif) |\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif) |\n\n> **😉 꿀팁!**\n슬라이딩 애니메이션을 만들기 위한 또다른 방법이 있습니다, 아래의 코드를 참조하세요:\n>>```let animation = GradientDirection.leftToRight.slidingAnimation()```\n\n### 👨‍👧‍👦 계층 구조\n\n```SkeletonView```는 재귀적입니다 , 그리고 우리는 skeleton이 효율적으로 작동하기를 원하기 때문에, 가능한 빨리 재귀작업을 중단하기를 원합니다. 이러한 이유때문에 반드시 컨테이너 뷰를  `Skeletonable` 로 설정해야 합니다,  `skeletonable` 되지 않는 뷰를 만나는 순간 재귀 작업을 중단하기 떄문입니다.\n\n아래의 이미지를 참고하세요 이미지는 한눈에 이해되실겁니다:\n\n> ```ìsSkeletonable```= ☠️\n\n| 설정값                             | 결과                                        |\n| ----------------------------------------- | --------------------------------------------- |\n| ![](../Assets/no_skeletonable.png)           | ![](../Assets/no_skeletonables_result.png)       |\n| ![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)       |\n| ![](../Assets/container_skeletonable.png)    | ![](../Assets/container_skeletonable_result.png) |\n| ![](../Assets/all_skeletonables.png)         | ![](../Assets/all_skeletonables_result.png)      |\n\n\n### 🔬 디버그\n\n**새로운소식** 어떤것들이 잘 동작 하지 않을때를 위해 디버그 작업을 용이하게 하기 위해서  `SkeletonView` 에는 몇가지 새로운 것들이 있습니다.\n\n첫번쨰로, `UIView` 에서 skeleton 정보를 보기위해 다음과 같이 지원하고 있습니다:\n```swift\nvar skeletonDescription: String\n\n```\nskeleton은 이렇게 생겼습니다:\n\n![](../Assets/debug_description.png)\n\n그리고, 새로운 **디버그 모드**를 활성화 시킬 수 있습니다. 간단하게 `SKELETON_DEBUG` 이라는 환경 변수를 추가해 활성화 하면 됩니다.\n\n![](../Assets/debug_mode.png)\n\n그런 이후 skeleton이 나오면 Xcode 콘솔창에서 계층 구조를 볼 수 있습니다.\n\n<details>\n<summary>예제를 확인해보세요. </summary>\n<img src=\"../Assets/hierarchy_output.png\" />\n</details>\n\n\n\n### 📚 문서화\n조금만 기다려주세요...😅\n\n### 📋 지원 가능한 OS & SDK 버전\n\n* iOS 9.0+\n* tvOS 9.0+\n* Swift 4.2\n\n## 📬 예정된 기능들\n\n* [x] 멀티라인 에서의 마지막 라인의 채우기 비율 설정\n* [x] 더많은 그라디언트 애니메이션\n* [x] resizable cells 지원\n* [x] CollectionView 호환\n* [x] tvOS 호환\n* [x] recovery state 추가\n* [x] Custom default appearance\n* [x] 디버그 모드\n* [ ] Custom collections 호환\n* [ ] skeletons 가 보이거나 가려질때 애니메이션 추가\n* [ ] MacOS 와 WatchOS 호환\n\n## ❤️ 기여하기\n이 프로젝트는 오픈소스 프로젝트 입니다, 마음편하게 기여해주시면 됩니다 어떻게 하냐구요?\n- 새로운 [이슈](https://github.com/Juanpe/SkeletonView/issues/new)를 등록합니다.\n- [email](mailto://juanpecatalan.com)을 보냅니다.\n- 당신의 수정을 제안합니다, pull request를 포함한 수정을 권장합니다.\n\n전체 [기여자목록](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\n###### [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)를 통해 프로젝트가 생성되었습니다\n\n## 📢 소식들\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n- [Swift News #36](https://www.youtube.com/watch?v=mAGpsQiy6so)\n\n\n\n## 👨🏻‍💻 개발자\n[1.1]: http://i.imgur.com/tXSoThF.png\n[1]: http://www.twitter.com/JuanpeCatalan\n\n* Juanpe Catalán [![alt text][1.1]][1]\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n## 👮🏻 라이센스\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "Translations/README_pt-br.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-master\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60\" /></a>\n    <img src=\"https://img.shields.io/badge/Swift-5-orange.svg\" />\n    <img src=\"http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green\" />\n    <img src=\"https://img.shields.io/badge/platforms-ios%2Btvos-green\" />\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n    <br/>\n    <a href=\"https://twitter.com/JuanpeCatalan\">\n        <img src=\"https://img.shields.io/badge/contact-@JuanpeCatalan-blue.svg?style=flat\" alt=\"Twitter: @JuanpeCatalan\" />\n    </a>\n    <a href=\"https://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge\">\n        <img src=\"https://badges.gitter.im/SkeletonView/community.svg?style=flat\" />\n    </a>\n    <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MJ4Y2D9DEX6FL&lc=ES&item_name=SkeletonView&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted\">\n        <img src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"PayPal\" />\n    <a href=\"https://twitter.com/intent/tweet?text=Wow%20This%20library%20is%20awesome:&url=https%3A%2F%2Fgithub.com%2FJuanpe%2FSkeletonView\">\n      <img src=\"https://img.shields.io/twitter/url/https/github.com/Juanpe/SkeletonView.svg?style=social\" alt=\"License\" />\n    </a>\n</p>\n\n**🌎 Traduções: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md) . [🇩🇪](README_de.md)**\n\nHoje, quase todos os apps têm processos assíncronos, como requisições de API, processos longos, etc. E enquanto os processos estão ocorrendo, normalmente os desenvolvedores usam uma view que mostra os usuarios que algo está ocorrendo.\n\n```SkeletonView``` foi criado para essa necessidade, um jeito elegante de mostrar aos usuários que algo está acontecendo e já prepará-los para qual conteúdo será carregado.\n\nAproveite! 🙂\n\n- [🌟 Features](#-features)\n  - [📋 Versões do SDK e OS suportados](#-versões-do-sdk-e-os-suportados)\n  - [🔮 Exemplo](#-exemplo)\n- [📲 Instalação](#-instalação)\n    - [Usando CocoaPods](#usando-cocoapods)\n    - [Usando Carthage](#usando-carthage)\n- [🐒 Como usar](#-como-usar)\n  - [🌿 Coleções](#-coleções)\n        - [UITableView](#uitableview)\n        - [UICollectionView](#uicollectionview)\n  - [📰 Texto de várias linhas](#-texto-de-várias-linhas)\n      - [🎛 Customização](#-customização)\n  - [🎨 Cores customizadas](#-cores-customizadas)\n        - [Imagem capturada do site https://flatuicolors.com](#imagem-capturada-do-site-httpsflatuicolorscom)\n  - [🦋 Aparência](#-aparência)\n  - [🤓 Animações customizadas](#-animações-customizadas)\n  - [👨‍👧‍👦 Hierarquia](#-hierarquia)\n  - [📚 Documentação](#-documentação)\n- [📬 Próximos passos](#-próximos-passos)\n- [❤️ Contribuindo](#️-contribuindo)\n        - [Projeto gerado com SwiftPlate](#projeto-gerado-com-swiftplate)\n- [📢 Menções](#-menções)\n- [👨🏻‍💻 Autor](#-autor)\n- [👮🏻 Licença](#-licença)\n\n\n## 🌟 Features\n\n- [x] Fácil de usar\n- [x] Todas as UIViews são skeletonables\n- [x] Completamente customizável\n- [x] Universal (iPhone & iPad)\n- [x] Interface Builder friendly\n- [x] Sintaxe simples em Swift\n- [x] Código leve e legível\n\n### 📋 Versões do SDK e OS suportados\n\n* iOS 9.0+\n* tvOS 9.0+\n* Swift 4.2\n\n### 🔮 Exemplo\n\nPara rodar o projeto de exemplo, clone o repositório e use o target `SkeletonViewExample`.\n\n## 📲 Instalação\n\n#### Usando [CocoaPods](https://cocoapods.org)\n\nEdite seu `Podfile` e especifíque a dependência:\n\n```ruby\npod \"SkeletonView\"\n```\n\n#### Usando [Carthage](https://github.com/carthage)\n\nEdite seu `Cartfile` e especifíque a dependência:\n\n```bash\ngithub \"Juanpe/SkeletonView\"\n```\n\n## 🐒 Como usar\n\nApenas **3** passos necessários para usar `SkeletonView`:\n\n**1.** Importe SkeletonView no lugar desejado.\n```swift\nimport SkeletonView\n```\n\n**2.** Agora, especifíque quais views serão `skeletonables`. Você consegue fazer isso de duas formas:\n\n**Usando código:**\n```swift\navatarImageView.isSkeletonable = true\n```\n**Usando IB/Storyboards:**\n\n![](../Assets/storyboard.png)\n\n**3.** Uma vez que você setou as views, você pode mostrar o **skeleton**. Para fazê-lo, você tem **4** escolhas:\n\n```swift\n(1) view.showSkeleton()                 // Solid\n(2) view.showGradientSkeleton()         // Gradient\n(3) view.showAnimatedSkeleton()         // Solid animated\n(4) view.showAnimatedGradientSkeleton() // Gradient animated\n```\n\n**Pré-visualização**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>Solid</center>\n</td>\n<td width=\"25%\">\n<center>Gradient</center>\n</td>\n<td width=\"25%\">\n<center>Solid Animated</center>\n</td>\n<td width=\"25%\">\n<center>Gradient Animated</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n> **IMPORTANTE!**\n>>```SkeletonView``` é recursivo, então se você quer mostrar o esqueleto em todas as views skeletonables, você só precisa chamar o método na main container view. Por exemplo, com UIViewControllers\n\n### 🌿 Coleções\n\n```SkeletonView``` é compatível com ```UITableView``` e ```UICollectionView```.\n\n###### UITableView\n\nSe você quer mostrar o skeleton em uma ```UITableView```, você precisa conformar com o protocolo ```SkeletonTableViewDataSource```.\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\nComo você pode ver, esse protocolo herda de ```UITableViewDataSource```, então você pode substituir esse protocolo com o protocolo do skeleton.\n\nEsse protocolo tem uma implementação padrão:\n\n``` swift\nfunc numSections(in collectionSkeletonView: UITableView) -> Int\n// Default: 1\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// Default:\n// It calculates how many cells need to populate whole tableview\n```\n\nEsse é o único método que você precisa implementar para informar o skeleton sobre o cell identifier. Esse método não possui uma implementação padrão:\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n ```\n\n**Exemplo**\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n\n> **IMPORTANTE!**\n> Se você está usando resizable cells (`tableView.rowHeight = UITableViewAutomaticDimension` ), é obrigatório definir a `estimatedRowHeight`.\n\n###### UICollectionView\n\nPara ```UICollectionView```, você precisa conformar com o protocolo ```SkeletonCollectionViewDataSource```.\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\nO resto do processo é o mesmo da ```UITableView```\n\n### 📰 Texto de várias linhas\n\n\n![](../Assets/multilines2.png)\n\nQuando você usar elementos com texto, ```SkeletonView``` desenha linhas para simular o texto.\nAlém disso, você pode decidir quantas linhas você quer. Se ```numberOfLines``` está setado para zero (0), haverá um cálculo para saber quantas linhas são necessárias para preencher o skeleton inteiro e será desenhado. Caso contrário, se você setar para um (1) ou qualquer outro número maior que zero, só serão desenhadas aquele número de linhas.\n\n##### 🎛 Customização\n\nVocê pode setar algumas propriedades para elementos de várias linhas.\n\n\n| Property | Values | Default | Preview\n| ------- | ------- |------- | -------\n| **Filling percent** of the last line. | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)\n| **Corner radius** of lines. (**NEW**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)\n\n\n\nPara modificar a percentagem ou o raio **usando código**, especifique as propriedades:\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\nOu, se você preferir use **IB/Storyboard**:\n\n![](../Assets/multiline_customize.png)\n\n### 🎨 Cores customizadas\n\nVocê pode decidir que cor o skeleton esta pintado. Você só precisa parametrizar a cor e o gradiente que deseja.\n\n**Usando cores sólidas**\n``` swift\nview.showSkeleton(usingColor: UIColor.gray) // Solid\n// or\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n**Usando gradientes**\n``` swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient) // Gradient\n```\n\nAlém do mais, ```SkeletonView``` tem 20 cores flat 🤙🏼\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange  ...```\n\n![](../Assets/flatcolors.png)\n###### Imagem capturada do site [https://flatuicolors.com](https://flatuicolors.com)\n\n### 🦋 Aparência\n\n**NOVIDADE** Os skeletons tem uma aparência padrão. Então, quando você não especifíca a cor, gradiente ou propriedades de várias linhas, `SkeletonView` usa os valores padrões.\n\nValores padrões:\n- **tintColor**: UIColor\n    - *default: .clouds*\n- **gradient**: SkeletonGradient\n  - *default: SkeletonGradient(baseColor: .clouds)*\n- **multilineHeight**: CGFloat\n  - *default: 15*\n- **multilineSpacing**: CGFloat\n  - *default: 10*\n- **multilineLastLineFillPercent**: Int\n  - *default: 70*\n- **multilineCornerRadius**: Int\n  - *default: 0*\n\nPara obter esses valores padrões você pode usar `SkeletonAppearance.default`. Usando essa propriedade você pode declarar os valores também:\n```Swift\nSkeletonAppearance.default.multilineHeight = 20\nSkeletonAppearance.default.tintColor = .green\n```\n\n\n### 🤓 Animações customizadas\n\n```SkeletonView``` tem duas animações pré-definidas, *pulse* para skeletons solidos e *sliding* para gradientes.\n\nAlém disso, se você quiser fazer suas próprias animações no skeleton, é muito fácil.\n\n\nSkeleton disponibiliza a função `showAnimatedSkeleton` que tem o closure ```SkeletonLayerAnimation``` onde você pode definir sua animação customizada.\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\nVocê pode chamar esta função assim:\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // Customize here your animation\n\n  return animation\n}\n```\n\nEstá disponível ```SkeletonAnimationBuilder```. É um construtor para ```SkeletonLayerAnimation```.\n\nHoje, você pode criar **sliding animations** para gradientes, decidindo a **direction** e setando a **duration** da animaçāo (padrão = 1.5s).\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` é um enum, com os seguintes cases:\n\n|  Direction | Preview\n|------- | -------\n| .leftRight | ![](../Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](../Assets/sliding_right_to_left.gif)\n| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 TRUQUE!**\nExiste outra forma de criar sliding animations, apenas usando este atalho:\n>>```let animation = GradientDirection.leftToRight.slidingAnimation()```\n\n### 👨‍👧‍👦 Hierarquia\n\nJá que ```SkeletonView``` é recursiva, e queremos que o skeleton seja muito eficiente, queremos parar a recursão assim que possível. Por este motivo, você deve setar a container view como `Skeletonable`, porque o Skeleton vai parar de procurar por subviews `skeletonable` assim que a view não for mais skeletonable, quebrando a recursão.\n\nPorque uma imagem vale mais que mil palavras:\n\n> ```ìsSkeletonable```= ☠️\n\n| Configuration | Result\n|------- | -------\n|![](../Assets/no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)\n|![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)\n|![](../Assets/container_skeletonable.png) | ![](../Assets/container_skeletonable_result.png)\n|![](../Assets/all_skeletonables.png) | ![](../Assets/all_skeletonables_result.png)\n\n\n\n### 📚 Documentação\nEm breve...😅\n\n## 📬 Próximos passos\n\n* [x] Setar o percentual de preenchimento da última linha em elementos de várias linhas\n* [x] Adicionar mais animações de gradiente\n* [x] Suporte para resizable cells\n* [x] Compatível com CollectionView\n* [x] Compatível com tvOS\n* [x] Adicionar recovery state\n* [x] Aparência padrão customizável\n* [ ] Compatível com coleções customizáveis\n* [ ] Adicionar animações quando mostra/esconde os skeletons\n* [ ] Compatível com MacOS e WatchOS\n\n## ❤️ Contribuindo\nEste é um projeto de código aberto, então sinta-se a vontade para contribuir. Como?\n- Abra uma [issue](https://github.com/Juanpe/SkeletonView/issues/new).\n- Envie feedback por [email](mailto://juanpecatalan.com).\n- Proponha seus próprios fixes, sugestões e abra um pull request com as alterações.\n\nVer [todos os contribuidores](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\n###### Projeto gerado com [SwiftPlate](https://github.com/JohnSundell/SwiftPlate)\n\n## 📢 Menções\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n\n\n\n## 👨🏻‍💻 Autor\n[1.1]: http://i.imgur.com/tXSoThF.png\n[1]: http://www.twitter.com/JuanpeCatalan\n\n* Juanpe Catalán [![alt text][1.1]][1]\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n## 👮🏻 Licença\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "Translations/README_zh.md",
    "content": "![](../Assets/header2.jpg)\n\n<p align=\"center\">\n    <a href=\"https://github.com/Juanpe/SkeletonView/actions?query=workflow%3ACI\">\n      <img src=\"https://github.com/Juanpe/SkeletonView/workflows/CI/badge.svg\">\n    </a>\n    <a href=\"https://codebeat.co/projects/github-com-juanpe-skeletonview-master\"><img alt=\"codebeat badge\" src=\"https://codebeat.co/badges/f854fdfd-31e5-4689-ba04-075d83653e60\" /></a>\n    <img src=\"https://img.shields.io/badge/Swift-5-orange.svg\" />\n    <img src=\"http://img.shields.io/badge/dependency%20manager-swiftpm%2Bcocoapods%2Bcarthage-green\" />\n    <img src=\"https://img.shields.io/badge/platforms-ios%2Btvos-green\" />\n    <a href=\"https://badge.bow-swift.io/recipe?name=SkeletonView&description=An%20elegant%20way%20to%20show%20users%20that%20something%20is%20happening%20and%20also%20prepare%20them%20to%20which%20contents%20he%20is%20waiting&url=https://github.com/juanpe/skeletonview&owner=Juanpe&avatar=https://avatars0.githubusercontent.com/u/1409041?v=4&tag=1.8.7\"><img src=\"https://raw.githubusercontent.com/bow-swift/bow-art/master/badges/nef-playgrounds-badge.svg\" alt=\"SkeletonView Playground\" style=\"height:20px\"></a>   \n    <br/>\n    <a href=\"https://twitter.com/JuanpeCatalan\">\n        <img src=\"https://img.shields.io/badge/contact-@JuanpeCatalan-blue.svg?style=flat\" alt=\"Twitter: @JuanpeCatalan\" />\n    </a>\n    <a href=\"https://gitter.im/SkeletonView/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge\">\n        <img src=\"https://badges.gitter.im/SkeletonView/community.svg?style=flat\" />\n    </a>\n    <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=MJ4Y2D9DEX6FL&lc=ES&item_name=SkeletonView&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted\">\n        <img src=\"https://img.shields.io/badge/Donate-PayPal-green.svg\" alt=\"PayPal\" />\n    <a href=\"https://twitter.com/intent/tweet?text=Wow%20This%20library%20is%20awesome:&url=https%3A%2F%2Fgithub.com%2FJuanpe%2FSkeletonView\">\n      <img src=\"https://img.shields.io/twitter/url/https/github.com/Juanpe/SkeletonView.svg?style=social\" alt=\"License\" />\n    </a>\n</p>\n\n**🌎 翻译: [🇬🇧](../README.md) . [🇨🇳](README_zh.md) . [🇧🇷](README_pt-br.md) . [🇰🇷](README_ko.md) . [🇫🇷](README_fr.md) . [🇩🇪](README_de.md)**\n\n今天，几乎所有的应用程序都有异步流程，例如：Api请求、长时间运行的流程等。虽然流程正在运行，但通常开发人员会设置一个加载视图来向用户显示正在发生的事情。\n\n```SkeletonView``` 已经构想出来满足这种需求，这是一种优雅的方式，向用户展示正在发生的事情，并为他们等待的内容做好准备。\n\n好好享受! 🙂\n\n- [🌟 特征](#-特征)\n  - [📋 版本要求](#-版本要求)\n  - [🔮 示例](#-示例)\n- [📲 安装](#-安装)\n    - [使用 CocoaPods](#使用-cocoapods)\n    - [使用 Carthage](#使用-carthage)\n- [🐒 如何使用](#-如何使用)\n  - [🌿 集合](#-集合)\n        - [UITableView](#uitableview)\n        - [UICollectionView](#uicollectionview)\n  - [📰 多行文字](#-多行文字)\n      - [🎛 定制](#-定制)\n  - [🎨 自定义颜色](#-自定义颜色)\n        - [从网站 https://flatuicolors.com捕获的图像](#从网站-httpsflatuicolorscom捕获的图像)\n  - [🤓 自定义动画](#-自定义动画)\n  - [👨‍👧‍👦 等级制度](#-等级制度)\n  - [📚 文档](#-文档)\n- [📬 下一步](#-下一步)\n- [❤️ 特约](#️-特约)\n        - [使用 SwiftPlate 生成的项目](#使用-swiftplate-生成的项目)\n- [📢 提及](#-提及)\n- [👨🏻‍💻 作者](#-作者)\n- [👮🏻 许可证](#-许可证)\n\n\n## 🌟 特征\n\n- [x] 使用方便\n- [x] 支持所有 UIView\n- [x] 完全可定制\n- [x] 通用（iPhone和iPad）\n- [x] Interface Builder 友好\n- [x] 简单的 Swift 语法\n- [x] 轻量级可读代码库\n\n### 📋 版本要求\n\n* iOS 10.0+\n* tvOS 10.0+\n* Swift 4.2\n\n### 🔮 示例\n\n要运行示例项目，请克隆并运行 `SkeletonViewExample` 项目。\n\n## 📲 安装\n\n#### 使用 [CocoaPods](https://cocoapods.org)\n\n使用 CocoaPods 编辑您的 Podfile 并指定依赖项：\n\n```ruby\npod \"SkeletonView\"\n```\n\n#### 使用 [Carthage](https://github.com/carthage)\n\n编辑您的 Cartfile 并指定依赖项:\n\n```bash\ngithub \"Juanpe/SkeletonView\"\n```\n\n## 🐒 如何使用\n\n只需 **3** 个步骤即可使用 `SkeletonView`:\n\n**1.** 在适当的位置导入SkeletonView\n```swift\nimport SkeletonView\n```\n\n**2.** 现在，您可以通过两种设置方式实现 `SkeletonView` 效果\n\n**使用纯代码：**\n```swift\navatarImageView.isSkeletonable = true\n```\n**使用 IB/Storyboards：**\n\n![](../Assets/storyboard.png)\n\n**3.** 设置视图后，可以显示 **skeleton**. 并且您有 **4** 种效果可供选择:\n\n```swift\n(1) view.showSkeleton()                 // 固体\n(2) view.showGradientSkeleton()         // 渐变\n(3) view.showAnimatedSkeleton()         // 纯色动画\n(4) view.showAnimatedGradientSkeleton() // 渐变动画\n```\n\n**Preview**\n\n<table>\n<tr>\n<td width=\"25%\">\n<center>固体</center>\n</td>\n<td width=\"25%\">\n<center>渐变</center>\n</td>\n<td width=\"25%\">\n<center>纯色动画</center>\n</td>\n<td width=\"25%\">\n<center>渐变动画</center>\n</td>\n</tr>\n<tr>\n<td width=\"25%\">\n<img src=\"../Assets/solid.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient.png\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/solid_animated.gif\"></img>\n</td>\n<td width=\"25%\">\n<img src=\"../Assets/gradient_animated.gif\"></img>\n</td>\n</tr>\n</table>\n\n> **重要!**\n>>```SkeletonView``` 是递归的，所以如果你想在所有可骨架化的视图中显示骨架，你只需要在主容器视图中调用show方法。例如，使用UIViewControllers\n\n### 🌿 集合\n\n现在，```SkeletonView``` 兼容 ```UITableView``` 和 ```UICollectionView```。\n\n###### UITableView\n\n如果你要显示 skeleton 在一个 ```UITableView```上，你需要符合 ```SkeletonTableViewDataSource``` 协议。\n\n``` swift\npublic protocol SkeletonTableViewDataSource: UITableViewDataSource {\n    func numSections(in collectionSkeletonView: UITableView) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n如您所见，此协议继承自 UITableViewDataSource，因此您可以使用骨架协议替换此协议。\n\n该协议具有默认实现：\n\n``` swift\nfunc numSections(in collectionSkeletonView: UITableView) -> Int\n// 默认值：1\n```\n\n``` swift\nfunc collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int\n// 默认值：\n// 它计算填充整个tableview需要多少个单元格\n```\n\n为了让Skeleton知道单元标识符，您只需要实现一种方法。此方法没有默认实现：\n\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier\n ```\n\n**示例**\n ``` swift\n func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {\n    return \"CellIdentifier\"\n}\n ```\n\n> **重要!**\n> 如果您使用可调整大小的单元格 (`tableView.rowHeight = UITableViewAutomaticDimension` )，则必须定义 `estimatedRowHeight`。\n\n###### UICollectionView\n\n要为 ```UICollectionView``` 设置效果, 您需要符合 ```SkeletonCollectionViewDataSource``` 协议。\n\n``` swift\npublic protocol SkeletonCollectionViewDataSource: UICollectionViewDataSource {\n    func numSections(in collectionSkeletonView: UICollectionView) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, numberOfItemsInSection section: Int) -> Int\n    func collectionSkeletonView(_ skeletonView: UICollectionView, cellIdentifierForItemAt indexPath: IndexPath) -> ReusableCellIdentifier\n}\n```\n\n其余操作与 ```UITableView``` 相同。\n\n### 📰 多行文字\n\n\n![](../Assets/multilines2.png)\n\n使用带有文本的元素时， ```SkeletonView``` 绘制线条以模拟文本。此外，您可以决定您想要多少行。如果 ```numberOfLines``` 设置为零，它将计算填充整个骨架所需的行数，并将绘制它。相反，如果将其设置为一，二或任何大于零的数字，它将只绘制此行数。\n\n##### 🎛 定制\n\n您可以为多行元素设置一些属性。\n\n\n| 属性 | 值范围 | 默认 | 延时\n| ------- | ------- |------- | -------\n| **Filling percent** 最后一行的长度百分比 | `0...100` | `70%` | ![](../Assets/multiline_lastline.png)\n| **Corner radius** 条目圆角半径. (**新**) | `0...10` | `0` | ![](../Assets/multiline_corner.png)\n\n\n\n**纯代码**修改百分比或半径：\n\n```swift\ndescriptionTextView.lastLineFillPercent = 50\ndescriptionTextView.linesCornerRadius = 5\n```\n\n或者，如果您更喜欢使用 **IB/Storyboard**:\n\n![](../Assets/multiline_customize.png)\n\n### 🎨 自定义颜色\n\n您可以决定 ```SkeletonView``` 的显示颜色。您只需要传递颜色或渐变的参数。\n\n**使用纯色**\n``` swift\nview.showSkeleton(usingColor: UIColor.gray) // 固体效果\n// 或者\nview.showSkeleton(usingColor: UIColor(red: 25.0, green: 30.0, blue: 255.0, alpha: 1.0))\n```\n**使用渐变色**\n``` swift\nlet gradient = SkeletonGradient(baseColor: UIColor.midnightBlue)\nview.showGradientSkeleton(usingGradient: gradient) // 梯度效果\n```\n\n此外， ```SkeletonView``` 附带的 20 种颜色 🤙🏼\n\n```UIColor.turquoise, UIColor.greenSea, UIColor.sunFlower, UIColor.flatOrange  ...```\n\n![](../Assets/flatcolors.png)\n###### 从网站 [https://flatuicolors.com](https://flatuicolors.com)捕获的图像\n\n### 🤓 自定义动画\n\n现在，```SkeletonView``` 有两个内置动画，*pulse* 脉冲效果和 *sliding* 渐变滑动效果。\n\n此外，如果你想做自己的 skeleton 动画，那真的很容易。\n\n\nSkeleton 提供了 `showAnimatedSkeleton` 一个具有 ```SkeletonLayerAnimation``` 闭包的功能，您可以在其中定义自定义动画。\n\n```swift\npublic typealias SkeletonLayerAnimation = (CALayer) -> CAAnimation\n```\n\n您可以像这样调用函数：\n\n```swift\nview.showAnimatedSkeleton { (layer) -> CAAnimation in\n  let animation = CAAnimation()\n  // 在这里自定义你的动画\n\n  return animation\n}\n```\n\n**新** 它可用 ```SkeletonAnimationBuilder```。这是一个 ```SkeletonLayerAnimation```的衍生。\n\n今天，您可以为渐变创建 **滑动动画**，确定 **方向** 并设置动画的 **持续时间**  (默认值 = 1.5s)。\n\n```swift\n// func makeSlidingAnimation(withDirection direction: GradientDirection, duration: CFTimeInterval = 1.5) -> SkeletonLayerAnimation\n\nlet animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftToRight)\nview.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)\n\n```\n\n```GradientDirection``` 是一个枚举，在这种情况下：\n\n|  方向 | 效果\n|------- | -------\n| .leftRight | ![](../Assets/sliding_left_to_right.gif)\n| .rightLeft | ![](../Assets/sliding_right_to_left.gif)\n| .topBottom | ![](../Assets/sliding_top_to_bottom.gif)\n| .bottomTop | ![](../Assets/sliding_bottom_to_top.gif)\n| .topLeftBottomRight | ![](../Assets/sliding_topLeft_to_bottomRight.gif)\n| .bottomRightTopLeft | ![](../Assets/sliding_bottomRight_to_topLeft.gif)\n\n> **😉 技巧!**\n存在另一种创建滑动动画的方法，只需使用此快捷方式：\n>>```let animation = GradientDirection.leftToRight.slidingAnimation()```\n\n### 👨‍👧‍👦 等级制度\n\n由于 ```SkeletonView``` 是递归的，我们希望 skeleton 效率高效, 我们希望尽快停止递归。因此，您必须将容器视图设置为 `Skeletonable` ，因为`skeletonable` 一旦视图不是 Skeletonable, Skeleton 将停止查找子视图，然后断开递归。\n\n一图胜千言：\n\n> 设置 ```ìsSkeletonable```= ☠️\n\n| 分组 | 结果\n|------- | -------\n|![](../Assets/no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)\n|![](../Assets/container_no_skeletonable.png) | ![](../Assets/no_skeletonables_result.png)\n|![](../Assets/container_skeletonable.png) | ![](../Assets/container_skeletonable_result.png)\n|![](../Assets/all_skeletonables.png) | ![](../Assets/all_skeletonables_result.png)\n\n\n\n### 📚 文档\n快出来...😅\n\n## 📬 下一步\n\n* [x] 设置多行元素中最后一行的填充百分比\n* [x] 添加更多渐变动画\n* [x] 支持可调整大小的单元\n* [x] CollectionView 兼容\n* [x] tvOS 兼容\n* [x] 添加恢复状态\n* [ ] 自定义集合兼容\n* [ ] 在显示/隐藏骨架时添加动画\n* [ ] MacOS 和 WatchOS兼容\n\n## ❤️ 特约\n这是一个开源项目，所以请随时贡献。怎么样？\n\n- 打开一个 [issue](https://github.com/Juanpe/SkeletonView/issues/new)\n- 反馈通过发送 [email](mailto://juanpecatalan.com)\n- 提出您自己的修复和建议，并带有拉取的请求。\n\n查看 [所有贡献者](https://github.com/Juanpe/SkeletonView/graphs/contributors)\n\n###### 使用 [SwiftPlate](https://github.com/JohnSundell/SwiftPlate) 生成的项目\n\n## 📢 提及\n\n- [iOS Dev Weekly #327](https://iosdevweekly.com/issues/327#start)\n- [Hacking with Swift Articles](https://www.hackingwithswift.com/articles/40/skeletonview-makes-loading-content-beautiful)\n- [Top 10 Swift Articles November](https://medium.mybridge.co/swift-top-10-articles-for-the-past-month-v-nov-2017-dfed7861cd65)\n- [30 Amazing iOS Swift Libraries (v2018)](https://medium.mybridge.co/30-amazing-ios-swift-libraries-for-the-past-year-v-2018-7cf15027eee9)\n- [AppCoda Weekly #44](http://digest.appcoda.com/issues/appcoda-weekly-issue-44-81899)\n- [iOS Cookies Newsletter #103](https://us11.campaign-archive.com/?u=cd1f3ed33c6527331d82107ba&id=48131a516d)\n- [Swift Developments Newsletter #113](https://andybargh.com/swiftdevelopments-113/)\n- [iOS Goodies #204](http://ios-goodies.com/post/167557280951/week-204)\n- [Swift Weekly #96](http://digest.swiftweekly.com/issues/swift-weekly-issue-96-81759)\n- [CocoaControls](https://www.cocoacontrols.com/controls/skeletonview)\n- [Awesome iOS Newsletter #74](https://ios.libhunt.com/newsletter/74)\n\n\n\n## 👨🏻‍💻 作者\n[1.1]: http://i.imgur.com/tXSoThF.png\n[1]: http://www.twitter.com/JuanpeCatalan\n\n* Juanpe Catalán [![alt text][1.1]][1]\n\n<a class=\"bmc-button\" target=\"_blank\" href=\"https://www.buymeacoffee.com/CDou4xtIK\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy me a coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\"><span style=\"margin-left:5px\"></span></a>\n\n## 👮🏻 许可证\n\n```\nMIT License\n\nCopyright (c) 2017 Juanpe Catalán\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n"
  },
  {
    "path": "fastlane/Fastfile",
    "content": "default_platform(:ios)\npodspec_name = \"SkeletonView.podspec\"\n\nlane :bump_version do |options|\n   version_bump_podspec(path: @podspec_name, version_number: options[:next_version])\nend\n\nlane :release_current do\n   version = version_get_podspec(path: @podspec_name)\n   if git_tag_exists(tag: version)\n   UI.user_error!(\"The tag #{version} already exists on the repo. To release a new version of the library bump the version on #{@podspec_name}\")\n   end\n   pod_lib_lint\n   add_git_tag(tag: \"#{version}\")\n   push_git_tags\n   pod_push\nend\n"
  },
  {
    "path": "fastlane/README.md",
    "content": "fastlane documentation\n----\n\n# Installation\n\nMake sure you have the latest version of the Xcode command line tools installed:\n\n```sh\nxcode-select --install\n```\n\nFor _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)\n\n# Available Actions\n\n### bump_version\n\n```sh\n[bundle exec] fastlane bump_version\n```\n\n\n\n### release_current\n\n```sh\n[bundle exec] fastlane release_current\n```\n\n\n\n----\n\nThis README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.\n\nMore information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).\n\nThe documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).\n"
  }
]