Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added additional support for multiple animations in DotLottie #2074

Merged
merged 22 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3265c1d
Updated DotLottieAnimation optional attributes
eharrison Dec 9, 2022
592c8ff
Added snapshot test files
eharrison Dec 9, 2022
b3b8d0c
Merge branch 'airbnb:master' into master
eharrison May 17, 2023
d68d573
[FEAT] Added support for playing animations in sequence by calling ne…
eharrison Jun 9, 2023
0c2fb11
[CHORE] Updated formatting
eharrison Jun 9, 2023
171a815
[CHORE] Updated snapshots
eharrison Jun 9, 2023
f9a94de
Update Sources/Public/Animation/LottieAnimationView.swift
eharrison Jun 13, 2023
71a493d
Merge branch 'airbnb:master' into master
eharrison Jun 13, 2023
e0a50e5
[FEAT] Added support for playing animations in sequence by calling ne…
eharrison Jun 9, 2023
381e0c5
[CHORE] Updated formatting
eharrison Jun 9, 2023
2a50d79
[CHORE] Updated snapshots
eharrison Jun 9, 2023
cf1b463
Removed unnecessary functions and made methods public to allow extern…
eharrison Jun 13, 2023
ef762a9
Updated loadAnimation function location to LottieAnimationLayer
eharrison Jun 13, 2023
5a47544
Merge remote-tracking branch 'origin/dotlottie-multiple-animations' i…
eharrison Jun 13, 2023
64dad0b
Merge remote-tracking branch 'origin/dotlottie-multiple-animations' i…
eharrison Jun 13, 2023
3e3ad13
Fixed merge issues
eharrison Jun 13, 2023
d0b7a85
Update Sources/Private/Model/DotLottie/DotLottieAnimation.swift
eharrison Jun 13, 2023
24bffff
Update Sources/Public/Animation/LottieAnimationLayer.swift
eharrison Jun 13, 2023
238fad2
Added configuration documentation
eharrison Jun 13, 2023
a150ac6
Made animations array public inside DotLottieFile and removed unneces…
eharrison Jun 13, 2023
be48380
Merge remote-tracking branch 'origin/dotlottie-multiple-animations' i…
eharrison Jun 13, 2023
143f8ad
Fixed formatting
eharrison Jun 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -248,5 +248,4 @@ class AnimationPreviewViewController: UIViewController {
animationView.animationSpeed = speed
configureSettingsMenu()
}

}
29 changes: 21 additions & 8 deletions Lottie.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,6 @@
6C48784728FF20140005AF07 /* DotLottieManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4877FB28FF20140005AF07 /* DotLottieManifest.swift */; };
6C48784828FF20140005AF07 /* DotLottieManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4877FB28FF20140005AF07 /* DotLottieManifest.swift */; };
6C48784928FF20140005AF07 /* DotLottieManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4877FB28FF20140005AF07 /* DotLottieManifest.swift */; };
6C48784B29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48784A29008ACF0005AF07 /* DotLottieConfiguration.swift */; };
6C48784C29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48784A29008ACF0005AF07 /* DotLottieConfiguration.swift */; };
6C48784D29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48784A29008ACF0005AF07 /* DotLottieConfiguration.swift */; };
6C48785229017CBF0005AF07 /* DotLottieCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785129017CBF0005AF07 /* DotLottieCacheProvider.swift */; };
6C48785329017CBF0005AF07 /* DotLottieCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785129017CBF0005AF07 /* DotLottieCacheProvider.swift */; };
6C48785429017CBF0005AF07 /* DotLottieCacheProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785129017CBF0005AF07 /* DotLottieCacheProvider.swift */; };
Expand All @@ -649,6 +646,9 @@
6C4878602901D8C70005AF07 /* DotLottieImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785F2901D8C70005AF07 /* DotLottieImageProvider.swift */; };
6C4878612901D8C70005AF07 /* DotLottieImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785F2901D8C70005AF07 /* DotLottieImageProvider.swift */; };
6C4878622901D8C70005AF07 /* DotLottieImageProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785F2901D8C70005AF07 /* DotLottieImageProvider.swift */; };
6C7698432A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7698422A38A71200E9BEF4 /* DotLottieConfiguration.swift */; };
6C7698442A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7698422A38A71200E9BEF4 /* DotLottieConfiguration.swift */; };
6C7698452A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7698422A38A71200E9BEF4 /* DotLottieConfiguration.swift */; };
6CC544932902FF7D00212722 /* DotLottieCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C48785529017D1D0005AF07 /* DotLottieCache.swift */; };
6D0E635F28246BD0007C5DB6 /* Difference in Frameworks */ = {isa = PBXBuildFile; productRef = 6D0E635E28246BD0007C5DB6 /* Difference */; };
6D99D6432823790700E5205B /* LegacyGradientFillRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D99D6422823790700E5205B /* LegacyGradientFillRenderer.swift */; };
Expand Down Expand Up @@ -916,11 +916,12 @@
6C4877E328FF20140005AF07 /* DotLottieFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DotLottieFile.swift; sourceTree = "<group>"; };
6C4877E428FF20140005AF07 /* DotLottieUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DotLottieUtils.swift; sourceTree = "<group>"; };
6C4877FB28FF20140005AF07 /* DotLottieManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DotLottieManifest.swift; sourceTree = "<group>"; };
6C48784A29008ACF0005AF07 /* DotLottieConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieConfiguration.swift; sourceTree = "<group>"; };
6C48785129017CBF0005AF07 /* DotLottieCacheProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieCacheProvider.swift; sourceTree = "<group>"; };
6C48785529017D1D0005AF07 /* DotLottieCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieCache.swift; sourceTree = "<group>"; };
6C4878592901811D0005AF07 /* DotLottieFileHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieFileHelpers.swift; sourceTree = "<group>"; };
6C48785F2901D8C70005AF07 /* DotLottieImageProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieImageProvider.swift; sourceTree = "<group>"; };
6C49605B2A33452900BDF3CB /* DotLottieAnimationMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotLottieAnimationMode.swift; sourceTree = "<group>"; };
6C7698422A38A71200E9BEF4 /* DotLottieConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DotLottieConfiguration.swift; sourceTree = "<group>"; };
6D99D6422823790700E5205B /* LegacyGradientFillRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacyGradientFillRenderer.swift; sourceTree = "<group>"; };
6DB3BDB528243FA5002A276D /* ValueProvidersTests.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = ValueProvidersTests.swift; sourceTree = "<group>"; tabWidth = 2; };
6DB3BDB7282454A6002A276D /* DictionaryInitializable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryInitializable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -977,6 +978,7 @@
2EAF59C027A0798600E00531 /* Sources */,
2E8040BA27A07343006E74CB /* Tests */,
2E80409B27A0725D006E74CB /* Products */,
6C7698412A38A6B800E9BEF4 /* Recovered References */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -1645,6 +1647,7 @@
children = (
6C4877E328FF20140005AF07 /* DotLottieFile.swift */,
6C4878592901811D0005AF07 /* DotLottieFileHelpers.swift */,
6C7698422A38A71200E9BEF4 /* DotLottieConfiguration.swift */,
6C48785D2901A4110005AF07 /* Cache */,
);
path = DotLottie;
Expand All @@ -1665,13 +1668,20 @@
6C4877FB28FF20140005AF07 /* DotLottieManifest.swift */,
6C4877E428FF20140005AF07 /* DotLottieUtils.swift */,
6C4877E228FF20140005AF07 /* DotLottieAnimation.swift */,
6C48784A29008ACF0005AF07 /* DotLottieConfiguration.swift */,
6C48785F2901D8C70005AF07 /* DotLottieImageProvider.swift */,
6CFA1077290B12B900873A98 /* ZipFoundation */,
);
path = DotLottie;
sourceTree = "<group>";
};
6C7698412A38A6B800E9BEF4 /* Recovered References */ = {
isa = PBXGroup;
children = (
6C49605B2A33452900BDF3CB /* DotLottieAnimationMode.swift */,
);
name = "Recovered References";
sourceTree = "<group>";
};
6CFA1077290B12B900873A98 /* ZipFoundation */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2021,6 +2031,7 @@
2EAF5AD727A0798700E00531 /* Vectors.swift in Sources */,
2E9C95E22822F43100677516 /* Group.swift in Sources */,
2E9C97112822F43100677516 /* Keyframes+combined.swift in Sources */,
6C49605C2A33452900BDF3CB /* DotLottieAnimationMode.swift in Sources */,
0887347B28F0CCDD00458627 /* LottieAnimationView.swift in Sources */,
2EAF5AD127A0798700E00531 /* AnimatedControl.swift in Sources */,
2E9C966F2822F43100677516 /* LayerTextProvider.swift in Sources */,
Expand All @@ -2034,7 +2045,6 @@
6C48780528FF20140005AF07 /* DotLottieUtils.swift in Sources */,
2E9C96B42822F43100677516 /* AnyNodeProperty.swift in Sources */,
2EAF5AF827A0798700E00531 /* FloatValueProvider.swift in Sources */,
6C48784B29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */,
2E9C968D2822F43100677516 /* PassThroughOutputNode.swift in Sources */,
087584CF29B2BC8200BC168F /* Data+Compression.swift in Sources */,
2EAF5AB627A0798700E00531 /* CompatibleAnimationKeypath.swift in Sources */,
Expand Down Expand Up @@ -2067,6 +2077,7 @@
2EAF5AFE27A0798700E00531 /* GradientValueProvider.swift in Sources */,
2E9C96BD2822F43100677516 /* AnyValueContainer.swift in Sources */,
2E9C96602822F43100677516 /* LayerFontProvider.swift in Sources */,
6C7698432A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */,
2E9C96242822F43100677516 /* KeyframeGroup.swift in Sources */,
2E9C96FF2822F43100677516 /* BaseAnimationLayer.swift in Sources */,
2E9C96AB2822F43100677516 /* GradientStrokeNode.swift in Sources */,
Expand Down Expand Up @@ -2269,6 +2280,7 @@
2EAF5AD827A0798700E00531 /* Vectors.swift in Sources */,
2E9C95E32822F43100677516 /* Group.swift in Sources */,
2E9C97122822F43100677516 /* Keyframes+combined.swift in Sources */,
6C49605D2A33452900BDF3CB /* DotLottieAnimationMode.swift in Sources */,
0887347C28F0CCDD00458627 /* LottieAnimationView.swift in Sources */,
2EAF5AD227A0798700E00531 /* AnimatedControl.swift in Sources */,
2E9C96702822F43100677516 /* LayerTextProvider.swift in Sources */,
Expand All @@ -2282,7 +2294,6 @@
6C48780628FF20140005AF07 /* DotLottieUtils.swift in Sources */,
2E9C96B52822F43100677516 /* AnyNodeProperty.swift in Sources */,
2EAF5AF927A0798700E00531 /* FloatValueProvider.swift in Sources */,
6C48784C29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */,
2E9C968E2822F43100677516 /* PassThroughOutputNode.swift in Sources */,
087584D029B2BC8200BC168F /* Data+Compression.swift in Sources */,
2EAF5AB727A0798700E00531 /* CompatibleAnimationKeypath.swift in Sources */,
Expand Down Expand Up @@ -2315,6 +2326,7 @@
2EAF5AFF27A0798700E00531 /* GradientValueProvider.swift in Sources */,
2E9C96BE2822F43100677516 /* AnyValueContainer.swift in Sources */,
2E9C96612822F43100677516 /* LayerFontProvider.swift in Sources */,
6C7698442A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */,
2E9C96252822F43100677516 /* KeyframeGroup.swift in Sources */,
2E9C97002822F43100677516 /* BaseAnimationLayer.swift in Sources */,
2E9C96AC2822F43100677516 /* GradientStrokeNode.swift in Sources */,
Expand Down Expand Up @@ -2493,6 +2505,7 @@
2EAF5AD927A0798700E00531 /* Vectors.swift in Sources */,
2E9C95E42822F43100677516 /* Group.swift in Sources */,
2E9C97132822F43100677516 /* Keyframes+combined.swift in Sources */,
6C49605E2A33452900BDF3CB /* DotLottieAnimationMode.swift in Sources */,
0887347D28F0CCDD00458627 /* LottieAnimationView.swift in Sources */,
2EAF5AD327A0798700E00531 /* AnimatedControl.swift in Sources */,
2E9C96712822F43100677516 /* LayerTextProvider.swift in Sources */,
Expand All @@ -2506,7 +2519,6 @@
6C48780728FF20140005AF07 /* DotLottieUtils.swift in Sources */,
2E9C96B62822F43100677516 /* AnyNodeProperty.swift in Sources */,
2EAF5AFA27A0798700E00531 /* FloatValueProvider.swift in Sources */,
6C48784D29008ACF0005AF07 /* DotLottieConfiguration.swift in Sources */,
2E9C968F2822F43100677516 /* PassThroughOutputNode.swift in Sources */,
087584D129B2BC8200BC168F /* Data+Compression.swift in Sources */,
2EAF5AB827A0798700E00531 /* CompatibleAnimationKeypath.swift in Sources */,
Expand Down Expand Up @@ -2539,6 +2551,7 @@
2EAF5B0027A0798700E00531 /* GradientValueProvider.swift in Sources */,
2E9C96BF2822F43100677516 /* AnyValueContainer.swift in Sources */,
2E9C96622822F43100677516 /* LayerFontProvider.swift in Sources */,
6C7698452A38A71200E9BEF4 /* DotLottieConfiguration.swift in Sources */,
2E9C96262822F43100677516 /* KeyframeGroup.swift in Sources */,
2E9C97012822F43100677516 /* BaseAnimationLayer.swift in Sources */,
2E9C96AD2822F43100677516 /* GradientStrokeNode.swift in Sources */,
Expand Down
18 changes: 16 additions & 2 deletions Sources/Private/Model/DotLottie/DotLottieAnimation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import Foundation

// MARK: - DotLottieAnimation

struct DotLottieAnimation: Codable {
/// Id of Animation
var id: String
Expand All @@ -21,11 +23,16 @@ struct DotLottieAnimation: Codable {
var direction: Int? = 1

/// mode - "bounce" | "normal"
var mode: String? = "normal"
var mode: DotLottieAnimationMode? = .normal

/// Loop mode for animation
var loopMode: LottieLoopMode {
mode == "bounce" ? .autoReverse : ((loop ?? false) ? .loop : .playOnce)
switch mode {
case .bounce:
return .autoReverse
case .normal, nil:
return ((loop ?? false) ? .loop : .playOnce)
}
}

/// Animation speed
Expand All @@ -41,3 +48,10 @@ struct DotLottieAnimation: Codable {
return try LottieAnimation.from(data: data)
}
}

// MARK: - DotLottieAnimationMode

enum DotLottieAnimationMode: String, Codable {
case normal
case bounce
}
15 changes: 0 additions & 15 deletions Sources/Private/Model/DotLottie/DotLottieConfiguration.swift

This file was deleted.

36 changes: 28 additions & 8 deletions Sources/Public/Animation/LottieAnimationLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -549,15 +549,24 @@ public class LottieAnimationLayer: CALayer {
from dotLottieFile: DotLottieFile)
{
guard let dotLottieAnimation = dotLottieFile.animation(for: animationId) else { return }
loadAnimation(dotLottieAnimation)
}

loopMode = dotLottieAnimation.configuration.loopMode
animationSpeed = CGFloat(dotLottieAnimation.configuration.speed)

if let imageProvider = dotLottieAnimation.configuration.imageProvider {
self.imageProvider = imageProvider
}

animation = dotLottieAnimation.animation
/// Sets the lottie file backing the animation layer. Setting this will clear the
/// layer's contents, completion blocks and current state. The new animation will
/// be loaded up and set to the beginning of its timeline.
/// The loopMode, animationSpeed and imageProvider will be set according
/// to lottie file settings
/// - Parameters:
/// - atIndex: Internal animation index to play.
/// Defaults to play first animation in file.
/// - dotLottieFile: Lottie file to play
public func loadAnimation(
atIndex index: Int,
from dotLottieFile: DotLottieFile)
{
guard let dotLottieAnimation = dotLottieFile.animation(at: index) else { return }
loadAnimation(dotLottieAnimation)
}

/// Reloads the images supplied to the animation from the `imageProvider`
Expand Down Expand Up @@ -787,6 +796,17 @@ public class LottieAnimationLayer: CALayer {
}
}

private func loadAnimation(_ dotLottieAnimation: DotLottieFile.Animation) {
loopMode = dotLottieAnimation.configuration.loopMode
animationSpeed = CGFloat(dotLottieAnimation.configuration.speed)

if let imageProvider = dotLottieAnimation.configuration.imageProvider {
self.imageProvider = imageProvider
}

animation = dotLottieAnimation.animation
}

func updateRasterizationState() {
if isAnimationPlaying {
animationLayer?.shouldRasterize = false
Expand Down
16 changes: 16 additions & 0 deletions Sources/Public/Animation/LottieAnimationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,22 @@ open class LottieAnimationView: LottieAnimationViewBase {
lottieAnimationLayer.loadAnimation(animationId, from: dotLottieFile)
}

/// Sets the lottie file backing the animation view. Setting this will clear the
/// view's contents, completion blocks and current state. The new animation will
/// be loaded up and set to the beginning of its timeline.
/// The loopMode, animationSpeed and imageProvider will be set according
/// to lottie file settings
/// - Parameters:
/// - atIndex: Internal animation index to play. Optional
/// Defaults to play first animation in file.
/// - dotLottieFile: Lottie file to play
public func loadAnimation(
eharrison marked this conversation as resolved.
Show resolved Hide resolved
atIndex index: Int,
from dotLottieFile: DotLottieFile)
{
lottieAnimationLayer.loadAnimation(atIndex: index, from: dotLottieFile)
}

/// Reloads the images supplied to the animation from the `imageProvider`
public func reloadImages() {
lottieAnimationLayer.reloadImages()
Expand Down
24 changes: 24 additions & 0 deletions Sources/Public/DotLottie/DotLottieConfiguration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// DotLottieConfiguration.swift
// Lottie
//
// Created by Evandro Hoffmann on 19/10/22.
//

// MARK: - DotLottieConfiguration

/// The `DotLottieConfiguration` model holds the presets extracted from DotLottieAnimation
/// The presets are used as input to setup `LottieAnimationView` before playing the animation.
public struct DotLottieConfiguration {
eharrison marked this conversation as resolved.
Show resolved Hide resolved
/// id of the animation
public var id: String

/// Animation Image Provider
public var imageProvider: AnimationImageProvider?

/// Loop behaviour of animation
public var loopMode: LottieLoopMode

/// Playback speed of animation
public var speed: Double
}
18 changes: 13 additions & 5 deletions Sources/Public/DotLottie/DotLottieFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,18 @@ public final class DotLottieFile {
try decompress(data: data, to: fileUrl)
}

// MARK: Internal
// MARK: Public

/// Definition for a single animation within a `DotLottieFile`
struct Animation {
let animation: LottieAnimation
let configuration: DotLottieConfiguration
public struct Animation {
public let animation: LottieAnimation
public let configuration: DotLottieConfiguration
}

/// List of `LottieAnimation` in the file
private(set) var animations: [Animation] = []
public private(set) var animations: [Animation] = []

// MARK: Internal

/// Image provider for animations
private(set) var imageProvider: AnimationImageProvider?
Expand All @@ -60,6 +62,12 @@ public final class DotLottieFile {
}
}

/// The `LottieAnimation` and `DotLottieConfiguration` for the given animation index in this file
func animation(at index: Int) -> DotLottieFile.Animation? {
guard index < animations.count else { return nil }
return animations[index]
}

// MARK: Private

private static let manifestFileName = "manifest.json"
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Supports Core Animation engine
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.