├── sample ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── layout │ │ │ ├── activity_default.xml │ │ │ ├── layout_anim.xml │ │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── AndroidManifest.xml │ │ └── assets │ │ └── 9squares-AlBoardman.json ├── proguard-rules.pro └── build.gradle ├── HTLoading ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── res │ │ ├── values-zh-rCN │ │ │ └── strings.xml │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── attrs.xml │ │ │ └── styles.xml │ │ ├── drawable │ │ │ └── dialog_bg.xml │ │ └── layout │ │ │ └── loading_view.xml │ │ └── kotlin │ │ └── com │ │ └── superlht │ │ └── htloading │ │ ├── listener │ │ ├── OnDialogDismissListener.kt │ │ └── DrawFinishListener.kt │ │ ├── spinkit │ │ ├── animation │ │ │ ├── interpolator │ │ │ │ ├── Ease.java │ │ │ │ ├── PathInterpolatorCompatBase.java │ │ │ │ ├── PathInterpolatorCompatApi21.java │ │ │ │ ├── KeyFrameInterpolator.java │ │ │ │ ├── PathInterpolatorCompat.java │ │ │ │ └── PathInterpolatorDonut.java │ │ │ ├── AnimationUtils.java │ │ │ ├── FloatProperty.java │ │ │ ├── IntProperty.java │ │ │ └── SpriteAnimatorBuilder.java │ │ ├── sprite │ │ │ ├── RectSprite.java │ │ │ ├── CircleSprite.java │ │ │ ├── RingSprite.java │ │ │ ├── CircleLayoutContainer.java │ │ │ ├── ShapeSprite.java │ │ │ ├── SpriteContainer.java │ │ │ └── Sprite.java │ │ ├── Style.java │ │ ├── style │ │ │ ├── RotatingCircle.java │ │ │ ├── MultiplePulse.java │ │ │ ├── MultiplePulseRing.java │ │ │ ├── Pulse.java │ │ │ ├── RotatingPlane.java │ │ │ ├── PulseRing.java │ │ │ ├── FadingCircle.java │ │ │ ├── Circle.java │ │ │ ├── DoubleBounce.java │ │ │ ├── CubeGrid.java │ │ │ ├── ThreeBounce.java │ │ │ ├── Wave.java │ │ │ ├── WanderingCubes.java │ │ │ ├── ChasingDots.java │ │ │ └── FoldingCube.java │ │ ├── SpriteFactory.java │ │ └── SpinKitView.java │ │ ├── view │ │ ├── BaseLoadingView.kt │ │ ├── LoadingView.kt │ │ ├── SuccessView.kt │ │ ├── FailedView.kt │ │ └── HTLoading.kt │ │ ├── util │ │ └── SizeUtil.kt │ │ └── manager │ │ └── HTLoadingManager.kt ├── proguard-rules.pro └── build.gradle ├── settings.gradle ├── CHANGELOG.md ├── img ├── Pulse.gif ├── Wave.gif ├── Circle.gif ├── CubeGrid.gif ├── Effect.gif ├── screen.gif ├── screen2.gif ├── spinkit.gif ├── CustomView.gif ├── ChasingDots.gif ├── DoubleBounce.gif ├── FadingCircle.gif ├── FoldingCube.gif ├── RotatingPlane.gif ├── ThreeBounce.gif ├── RotatingCircle.gif └── WanderingCubes.gif ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── Sample └── src │ └── main │ └── kotlin │ └── com │ └── superlht │ └── dialogsample │ ├── SpinKitActivity.kt │ ├── DefaultActivity.kt │ ├── MainActivity.kt │ └── CustomActivity.kt ├── gradle.properties ├── gradlew.bat ├── README-EN.md ├── README.md └── gradlew /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /HTLoading/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':Sample', ':HTLoading' 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | ### v1.0.1:增加了SpinKit动画,可以直接通过showSpinKit(style:Int)方法调用 -------------------------------------------------------------------------------- /img/Pulse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/Pulse.gif -------------------------------------------------------------------------------- /img/Wave.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/Wave.gif -------------------------------------------------------------------------------- /img/Circle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/Circle.gif -------------------------------------------------------------------------------- /img/CubeGrid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/CubeGrid.gif -------------------------------------------------------------------------------- /img/Effect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/Effect.gif -------------------------------------------------------------------------------- /img/screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/screen.gif -------------------------------------------------------------------------------- /img/screen2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/screen2.gif -------------------------------------------------------------------------------- /img/spinkit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/spinkit.gif -------------------------------------------------------------------------------- /img/CustomView.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/CustomView.gif -------------------------------------------------------------------------------- /img/ChasingDots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/ChasingDots.gif -------------------------------------------------------------------------------- /img/DoubleBounce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/DoubleBounce.gif -------------------------------------------------------------------------------- /img/FadingCircle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/FadingCircle.gif -------------------------------------------------------------------------------- /img/FoldingCube.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/FoldingCube.gif -------------------------------------------------------------------------------- /img/RotatingPlane.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/RotatingPlane.gif -------------------------------------------------------------------------------- /img/ThreeBounce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/ThreeBounce.gif -------------------------------------------------------------------------------- /img/RotatingCircle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/RotatingCircle.gif -------------------------------------------------------------------------------- /img/WanderingCubes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/img/WanderingCubes.gif -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /HTLoading/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HartleyLau/HTLoading/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /HTLoading/src/main/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 加载失败 3 | 加载成功 4 | 正在加载 5 | 6 | -------------------------------------------------------------------------------- /HTLoading/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Failed to load 3 | Success to load 4 | Loading 5 | 6 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/listener/OnDialogDismissListener.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.listener 2 | 3 | /** 4 | * Created by Hatim Liu on 2017/8/17. 5 | */ 6 | interface OnDialogDismissListener { 7 | fun dialogDismiss() 8 | } -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HTLoading 3 | 4 | 显示默认效果 5 | 显示自定义加载效果 6 | 显示SpinKit动画 7 | 8 | 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Sep 17 01:14:10 CST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/listener/DrawFinishListener.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.listener 2 | 3 | import android.view.View 4 | 5 | /** 6 | * Created by Hatim Liu on 2017/8/16. 7 | */ 8 | interface DrawFinishListener { 9 | fun onDrawFinished(view: View) 10 | } -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_default.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/Ease.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.animation.interpolator; 2 | 3 | import android.view.animation.Interpolator; 4 | 5 | /** 6 | * Created by ybq. 7 | */ 8 | public class Ease { 9 | public static Interpolator inOut() { 10 | return PathInterpolatorCompat.create(0.42f, 0f, 0.58f, 1f); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/layout_anim.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /HTLoading/src/main/res/drawable/dialog_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/RectSprite.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | 7 | /** 8 | * Created by ybq. 9 | */ 10 | public class RectSprite extends ShapeSprite { 11 | @Override 12 | public ValueAnimator onCreateAnimation() { 13 | return null; 14 | } 15 | 16 | @Override 17 | public void drawShape(Canvas canvas, Paint paint) { 18 | if (getDrawBounds() != null) { 19 | canvas.drawRect(getDrawBounds(), paint); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Sample/src/main/kotlin/com/superlht/dialogsample/SpinKitActivity.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.dialogsample 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import com.superlht.htloading.view.HTLoading 6 | 7 | /** 8 | * Created by Hatim Liu on 2017/9/17. 9 | */ 10 | class SpinKitActivity : AppCompatActivity() { 11 | override fun onCreate(savedInstanceState: Bundle?) { 12 | super.onCreate(savedInstanceState) 13 | setContentView(R.layout.activity_default) 14 | val loading = HTLoading(this) 15 | loading.setInterceptBack(false) 16 | loading.showSpinKit(R.style.SpinKitView_CubeGrid) 17 | } 18 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/Style.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit; 2 | 3 | /** 4 | * Created by ybq. 5 | */ 6 | public enum Style { 7 | 8 | ROTATING_PLANE(0), 9 | DOUBLE_BOUNCE(1), 10 | WAVE(2), 11 | WANDERING_CUBES(3), 12 | PULSE(4), 13 | CHASING_DOTS(5), 14 | THREE_BOUNCE(6), 15 | CIRCLE(7), 16 | CUBE_GRID(8), 17 | FADING_CIRCLE(9), 18 | FOLDING_CUBE(10), 19 | ROTATING_CIRCLE(11), 20 | MULTIPLE_PULSE(12), 21 | PULSE_RING(13), 22 | MULTIPLE_PULSE_RING(14); 23 | 24 | @SuppressWarnings({"FieldCanBeLocal", "unused"}) 25 | private int value; 26 | 27 | Style(int value) { 28 | this.value = value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Sample/src/main/kotlin/com/superlht/dialogsample/DefaultActivity.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.dialogsample 2 | import android.os.Bundle 3 | import android.support.v7.app.AppCompatActivity 4 | import com.superlht.htloading.view.HTLoading 5 | import org.jetbrains.anko.doAsync 6 | import org.jetbrains.anko.uiThread 7 | 8 | /** 9 | * Created by lht on 2017-09-13. 10 | */ 11 | class DefaultActivity : AppCompatActivity() { 12 | override fun onCreate(savedInstanceState: Bundle?) { 13 | super.onCreate(savedInstanceState) 14 | setContentView(R.layout.activity_main) 15 | val loading = HTLoading(this) 16 | loading.show() 17 | doAsync { 18 | Thread.sleep(1000) 19 | uiThread { loading.showFailed() } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/RotatingCircle.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | 5 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 6 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 7 | 8 | 9 | public class RotatingCircle extends CircleSprite { 10 | 11 | @Override 12 | public ValueAnimator onCreateAnimation() { 13 | float fractions[] = new float[]{0f, 0.5f, 1f}; 14 | return new SpriteAnimatorBuilder(this). 15 | rotateX(fractions, 0, -180, -180). 16 | rotateY(fractions, 0, 0, -180). 17 | duration(1200). 18 | easeInOut(fractions) 19 | .build(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/MultiplePulse.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | 4 | import com.superlht.htloading.spinkit.sprite.Sprite; 5 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 6 | 7 | /** 8 | * Created by ybq. 9 | */ 10 | public class MultiplePulse extends SpriteContainer { 11 | @Override 12 | public Sprite[] onCreateChild() { 13 | return new Sprite[]{ 14 | new Pulse(), 15 | new Pulse(), 16 | new Pulse(), 17 | }; 18 | } 19 | 20 | @Override 21 | public void onChildCreated(Sprite... sprites) { 22 | for (int i = 0; i < sprites.length; i++) { 23 | sprites[i].setAnimationDelay(200 * (i + 1)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sample/src/main/kotlin/com/superlht/dialogsample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.dialogsample 2 | 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import kotlinx.android.synthetic.main.activity_main.* 6 | import org.jetbrains.anko.startActivity 7 | 8 | class MainActivity : AppCompatActivity() { 9 | 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | setContentView(R.layout.activity_main) 13 | listView.setOnItemClickListener { _, _, p, _ -> 14 | when (p) { 15 | 0 -> startActivity() 16 | 1 -> startActivity() 17 | 2 -> startActivity() 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/MultiplePulseRing.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | 4 | import com.superlht.htloading.spinkit.sprite.Sprite; 5 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 6 | 7 | /** 8 | * Created by ybq. 9 | */ 10 | public class MultiplePulseRing extends SpriteContainer { 11 | 12 | @Override 13 | public Sprite[] onCreateChild() { 14 | return new Sprite[]{ 15 | new PulseRing(), 16 | new PulseRing(), 17 | new PulseRing(), 18 | }; 19 | } 20 | 21 | @Override 22 | public void onChildCreated(Sprite... sprites) { 23 | for (int i = 0; i < sprites.length; i++) { 24 | sprites[i].setAnimationDelay(200 * (i + 1)); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /HTLoading/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/CircleSprite.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | 7 | /** 8 | * Created by ybq. 9 | */ 10 | public class CircleSprite extends ShapeSprite { 11 | 12 | @Override 13 | public ValueAnimator onCreateAnimation() { 14 | return null; 15 | } 16 | 17 | @Override 18 | public void drawShape(Canvas canvas, Paint paint) { 19 | if (getDrawBounds() != null) { 20 | int radius = Math.min(getDrawBounds().width(), getDrawBounds().height()) / 2; 21 | canvas.drawCircle(getDrawBounds().centerX(), 22 | getDrawBounds().centerY(), 23 | radius, paint); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/Pulse.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | 5 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 6 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 7 | 8 | 9 | /** 10 | * Created by ybq. 11 | */ 12 | public class Pulse extends CircleSprite { 13 | 14 | public Pulse() { 15 | setScale(0f); 16 | } 17 | 18 | @Override 19 | public ValueAnimator onCreateAnimation() { 20 | float fractions[] = new float[]{0f, 1f}; 21 | return new SpriteAnimatorBuilder(this). 22 | scale(fractions, 0f, 1f). 23 | alpha(fractions, 255, 0). 24 | duration(1000). 25 | easeInOut(fractions) 26 | .build(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/RingSprite.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | 7 | /** 8 | * Created by ybq. 9 | */ 10 | public class RingSprite extends ShapeSprite { 11 | 12 | 13 | @Override 14 | public void drawShape(Canvas canvas, Paint paint) { 15 | if (getDrawBounds() != null) { 16 | paint.setStyle(Paint.Style.STROKE); 17 | int radius = Math.min(getDrawBounds().width(), getDrawBounds().height()) / 2; 18 | paint.setStrokeWidth(radius / 12); 19 | canvas.drawCircle(getDrawBounds().centerX(), 20 | getDrawBounds().centerY(), 21 | radius, paint); 22 | } 23 | } 24 | 25 | @Override 26 | public ValueAnimator onCreateAnimation() { 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/view/BaseLoadingView.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.View 6 | import com.superlht.htloading.manager.HTLoadingManager 7 | 8 | /** 9 | * Created by lht on 2017-09-13. 10 | */ 11 | open class BaseLoadingView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { 12 | protected var mWidth = 0f 13 | protected var mPadding = 0f 14 | protected var color = HTLoadingManager.drawColor 15 | 16 | fun setDrawColor(color: Int) { 17 | this.color = color 18 | } 19 | 20 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 21 | super.onMeasure(widthMeasureSpec, heightMeasureSpec) 22 | mWidth = if (measuredWidth > height) 23 | measuredHeight.toFloat() 24 | else 25 | measuredWidth.toFloat() 26 | mPadding = 5f 27 | } 28 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/RotatingPlane.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.RectSprite; 8 | 9 | 10 | /** 11 | * Created by ybq. 12 | */ 13 | public class RotatingPlane extends RectSprite { 14 | @Override 15 | protected void onBoundsChange(Rect bounds) { 16 | setDrawBounds(clipSquare(bounds)); 17 | } 18 | 19 | @Override 20 | public ValueAnimator onCreateAnimation() { 21 | float fractions[] = new float[]{0f, 0.5f, 1f}; 22 | return new SpriteAnimatorBuilder(this). 23 | rotateX(fractions, 0, -180, -180). 24 | rotateY(fractions, 0, 0, -180). 25 | duration(1200). 26 | easeInOut(fractions) 27 | .build(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/PulseRing.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | 5 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 6 | import com.superlht.htloading.spinkit.animation.interpolator.KeyFrameInterpolator; 7 | import com.superlht.htloading.spinkit.sprite.RingSprite; 8 | 9 | 10 | /** 11 | * Created by ybq. 12 | */ 13 | public class PulseRing extends RingSprite { 14 | 15 | public PulseRing() { 16 | setScale(0f); 17 | } 18 | 19 | @Override 20 | public ValueAnimator onCreateAnimation() { 21 | float fractions[] = new float[]{0f, 0.7f, 1f}; 22 | return new SpriteAnimatorBuilder(this). 23 | scale(fractions, 0f, 1f, 1f). 24 | alpha(fractions, 255, (int) (255 * 0.7), 0). 25 | duration(1000). 26 | interpolator(KeyFrameInterpolator.pathInterpolator(0.21f, 0.53f, 0.56f, 0.8f, fractions)). 27 | build(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Sample/src/main/kotlin/com/superlht/dialogsample/CustomActivity.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.dialogsample 2 | import android.graphics.Color 3 | import android.os.Bundle 4 | import android.support.v7.app.AppCompatActivity 5 | import com.superlht.dialogsample.R 6 | import com.superlht.htloading.util.SizeUtil 7 | import com.superlht.htloading.view.HTLoading 8 | 9 | /** 10 | * Created by lht on 2017-09-13. 11 | */ 12 | class CustomActivity : AppCompatActivity() { 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.activity_default) 16 | val view = layoutInflater.inflate(R.layout.layout_anim, null) 17 | val loading = HTLoading(this) 18 | .setLoadingView(view) 19 | .setSize(SizeUtil.dip2px(this, 300f)) 20 | .setCustomViewSize(SizeUtil.dip2px(this, 250f)) 21 | .setDialogBackground(Color.TRANSPARENT) 22 | .setInterceptBack(false) 23 | loading.showCustomLoading() 24 | } 25 | } -------------------------------------------------------------------------------- /HTLoading/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 26 9 | buildToolsVersion "26.0.1" 10 | defaultConfig { 11 | applicationId "com.superlht.dialogsample" 12 | minSdkVersion 15 13 | targetSdkVersion 26 14 | versionCode 1 15 | versionName "1.0" 16 | } 17 | sourceSets { 18 | main { 19 | java.srcDirs = [ 20 | 'src/main/kotlin' 21 | ] 22 | } 23 | } 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation fileTree(include: ['*.jar'], dir: 'libs') 34 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 35 | implementation "org.jetbrains.anko:anko:0.10.1" 36 | implementation 'com.android.support:appcompat-v7:26.0.2' 37 | implementation 'com.airbnb.android:lottie:2.2.1' 38 | implementation project(':HTLoading') 39 | } 40 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/util/SizeUtil.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.util 2 | 3 | import android.content.Context 4 | 5 | /** 6 | * Created by Hatim Liu on 2017/8/17. 7 | * 屏幕尺寸计算的相关类 8 | */ 9 | class SizeUtil { 10 | companion object { 11 | 12 | /** 13 | * dp转px 14 | */ 15 | fun dip2px(context: Context, dpValue: Float): Int { 16 | val scale = context.resources.displayMetrics.density 17 | return (dpValue * scale + 0.5f).toInt() 18 | } 19 | 20 | /** 21 | * px转dp 22 | */ 23 | fun px2dip(context: Context, pxValue: Float): Int { 24 | val scale = context.resources.displayMetrics.density 25 | return (pxValue / scale + 0.5f).toInt() 26 | } 27 | 28 | /** 29 | * px转sp 30 | */ 31 | fun px2sp(context: Context, spValue: Float): Int { 32 | val fontScale = context.resources.displayMetrics.scaledDensity 33 | return (spValue / fontScale + 0.5f).toInt() 34 | } 35 | 36 | /** 37 | * sp转px 38 | */ 39 | fun sp2px(context: Context, spValue: Float): Int { 40 | val fontScale = context.resources.displayMetrics.scaledDensity 41 | return (spValue * fontScale + 0.5f).toInt() 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/CircleLayoutContainer.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Rect; 5 | 6 | /** 7 | * Created by ybq. 8 | */ 9 | public abstract class CircleLayoutContainer extends SpriteContainer { 10 | 11 | @Override 12 | public void drawChild(Canvas canvas) { 13 | for (int i = 0; i < getChildCount(); i++) { 14 | Sprite sprite = getChildAt(i); 15 | int count = canvas.save(); 16 | canvas.rotate(i * 360 / getChildCount(), 17 | getBounds().centerX(), 18 | getBounds().centerY()); 19 | sprite.draw(canvas); 20 | canvas.restoreToCount(count); 21 | } 22 | } 23 | 24 | @Override 25 | protected void onBoundsChange(Rect bounds) { 26 | super.onBoundsChange(bounds); 27 | bounds = clipSquare(bounds); 28 | int radius = (int) (bounds.width() * Math.PI / 3.6f / getChildCount()); 29 | int left = bounds.centerX() - radius; 30 | int right = bounds.centerX() + radius; 31 | for (int i = 0; i < getChildCount(); i++) { 32 | Sprite sprite = getChildAt(i); 33 | sprite.setDrawBounds(left, bounds.top, right, bounds.top + radius * 2); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/FadingCircle.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.os.Build; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.CircleLayoutContainer; 8 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 9 | import com.superlht.htloading.spinkit.sprite.Sprite; 10 | 11 | 12 | /** 13 | * Created by ybq. 14 | */ 15 | public class FadingCircle extends CircleLayoutContainer { 16 | 17 | @Override 18 | public Sprite[] onCreateChild() { 19 | Dot[] dots = new Dot[12]; 20 | for (int i = 0; i < dots.length; i++) { 21 | dots[i] = new Dot(); 22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 23 | dots[i].setAnimationDelay(1200 / 12 * i); 24 | } else { 25 | dots[i].setAnimationDelay(1200 / 12 * i + -1200); 26 | } 27 | } 28 | return dots; 29 | } 30 | 31 | private class Dot extends CircleSprite { 32 | 33 | Dot() { 34 | setAlpha(0); 35 | } 36 | 37 | @Override 38 | public ValueAnimator onCreateAnimation() { 39 | float fractions[] = new float[]{0f, 0.39f, 0.4f, 1f}; 40 | return new SpriteAnimatorBuilder(this). 41 | alpha(fractions, 0, 0, 255, 0). 42 | duration(1200). 43 | easeInOut(fractions).build(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/AnimationUtils.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.animation; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ValueAnimator; 5 | 6 | import com.superlht.htloading.spinkit.sprite.Sprite; 7 | 8 | 9 | /** 10 | * Created by ybq. 11 | */ 12 | public class AnimationUtils { 13 | 14 | public static void start(Animator animator) { 15 | if (animator != null && !animator.isStarted()) { 16 | animator.start(); 17 | } 18 | } 19 | 20 | public static void stop(Animator animator) { 21 | if (animator != null && !animator.isRunning()) { 22 | animator.end(); 23 | } 24 | } 25 | 26 | public static void start(Sprite... sprites) { 27 | for (Sprite sprite : sprites) { 28 | sprite.start(); 29 | } 30 | } 31 | 32 | public static void stop(Sprite... sprites) { 33 | for (Sprite sprite : sprites) { 34 | sprite.stop(); 35 | } 36 | } 37 | 38 | public static boolean isRunning(Sprite... sprites) { 39 | for (Sprite sprite : sprites) { 40 | if (sprite.isRunning()) { 41 | return true; 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | public static boolean isRunning(ValueAnimator animator) { 48 | return animator != null && animator.isRunning(); 49 | } 50 | 51 | public static boolean isStarted(ValueAnimator animator) { 52 | return animator != null && animator.isStarted(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/Circle.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.os.Build; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.CircleLayoutContainer; 8 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 9 | import com.superlht.htloading.spinkit.sprite.Sprite; 10 | 11 | 12 | /** 13 | * Created by ybq. 14 | */ 15 | public class Circle extends CircleLayoutContainer { 16 | 17 | @Override 18 | public Sprite[] onCreateChild() { 19 | Dot[] dots = new Dot[12]; 20 | for (int i = 0; i < dots.length; i++) { 21 | dots[i] = new Dot(); 22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 23 | dots[i].setAnimationDelay(1200 / 12 * i); 24 | } else { 25 | dots[i].setAnimationDelay(1200 / 12 * i + -1200); 26 | } 27 | } 28 | return dots; 29 | } 30 | 31 | private class Dot extends CircleSprite { 32 | 33 | Dot() { 34 | setScale(0f); 35 | } 36 | 37 | @Override 38 | public ValueAnimator onCreateAnimation() { 39 | float fractions[] = new float[]{0f, 0.5f, 1f}; 40 | return new SpriteAnimatorBuilder(this). 41 | scale(fractions, 0f, 1f, 0f). 42 | duration(1200). 43 | easeInOut(fractions) 44 | .build(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/DoubleBounce.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.os.Build; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 8 | import com.superlht.htloading.spinkit.sprite.Sprite; 9 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 10 | 11 | 12 | /** 13 | * Created by ybq. 14 | */ 15 | public class DoubleBounce extends SpriteContainer { 16 | 17 | @Override 18 | public Sprite[] onCreateChild() { 19 | return new Sprite[]{ 20 | new Bounce(), new Bounce() 21 | }; 22 | } 23 | 24 | @Override 25 | public void onChildCreated(Sprite... sprites) { 26 | super.onChildCreated(sprites); 27 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 28 | sprites[1].setAnimationDelay(1000); 29 | } else { 30 | sprites[1].setAnimationDelay(-1000); 31 | } 32 | } 33 | 34 | private class Bounce extends CircleSprite { 35 | 36 | Bounce() { 37 | setAlpha(153); 38 | setScale(0f); 39 | } 40 | 41 | @Override 42 | public ValueAnimator onCreateAnimation() { 43 | float fractions[] = new float[]{0f, 0.5f, 1f}; 44 | return new SpriteAnimatorBuilder(this).scale(fractions, 0f, 1f, 0f). 45 | duration(2000). 46 | easeInOut(fractions) 47 | .build(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/PathInterpolatorCompatBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.superlht.htloading.spinkit.animation.interpolator; 18 | 19 | import android.graphics.Path; 20 | import android.view.animation.Interpolator; 21 | 22 | /** 23 | * Base implementation for path interpolator compatibility. 24 | */ 25 | class PathInterpolatorCompatBase { 26 | 27 | private PathInterpolatorCompatBase() { 28 | // prevent instantiation 29 | } 30 | 31 | public static Interpolator create(Path path) { 32 | return new PathInterpolatorDonut(path); 33 | } 34 | 35 | public static Interpolator create(float controlX, float controlY) { 36 | return new PathInterpolatorDonut(controlX, controlY); 37 | } 38 | 39 | public static Interpolator create(float controlX1, float controlY1, 40 | float controlX2, float controlY2) { 41 | return new PathInterpolatorDonut(controlX1, controlY1, controlX2, controlY2); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/ShapeSprite.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Color; 5 | import android.graphics.ColorFilter; 6 | import android.graphics.Paint; 7 | 8 | /** 9 | * Created by ybq. 10 | */ 11 | public abstract class ShapeSprite extends Sprite { 12 | 13 | private Paint mPaint; 14 | private int mUseColor; 15 | private int mBaseColor; 16 | 17 | public ShapeSprite() { 18 | setColor(Color.WHITE); 19 | mPaint = new Paint(); 20 | mPaint.setAntiAlias(true); 21 | mPaint.setColor(mUseColor); 22 | } 23 | 24 | @Override 25 | public void setColor(int color) { 26 | mBaseColor = color; 27 | updateUseColor(); 28 | } 29 | 30 | @Override 31 | public int getColor() { 32 | return mBaseColor; 33 | } 34 | 35 | @SuppressWarnings("unused") 36 | public int getUseColor() { 37 | return mUseColor; 38 | } 39 | 40 | @Override 41 | public void setAlpha(int alpha) { 42 | super.setAlpha(alpha); 43 | updateUseColor(); 44 | } 45 | 46 | private void updateUseColor() { 47 | int alpha = getAlpha(); 48 | alpha += alpha >> 7; 49 | final int baseAlpha = mBaseColor >>> 24; 50 | final int useAlpha = baseAlpha * alpha >> 8; 51 | mUseColor = (mBaseColor << 8 >>> 8) | (useAlpha << 24); 52 | } 53 | 54 | @Override 55 | public void setColorFilter(ColorFilter colorFilter) { 56 | mPaint.setColorFilter(colorFilter); 57 | } 58 | 59 | @Override 60 | protected final void drawSelf(Canvas canvas) { 61 | mPaint.setColor(mUseColor); 62 | drawShape(canvas, mPaint); 63 | } 64 | 65 | public abstract void drawShape(Canvas canvas, Paint paint); 66 | } 67 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/FloatProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.superlht.htloading.spinkit.animation; 17 | 18 | import android.util.Property; 19 | 20 | /** 21 | * An implementation of {@link Property} to be used specifically with fields of type 22 | * float. This type-specific subclass enables performance benefit by allowing 23 | * calls to a {@link #set(Object, Float) set()} function that takes the primitive 24 | * float type and avoids autoboxing and other overhead associated with the 25 | * Float class. 26 | * 27 | * @param The class on which the Property is declared. 28 | */ 29 | public abstract class FloatProperty extends Property { 30 | 31 | public FloatProperty(String name) { 32 | super(Float.class, name); 33 | } 34 | 35 | /** 36 | * A type-specific override of the {@link #set(Object, Float)} that is faster when dealing 37 | * with fields of type float. 38 | */ 39 | public abstract void setValue(T object, float value); 40 | 41 | @Override 42 | final public void set(T object, Float value) { 43 | setValue(object, value); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/IntProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.superlht.htloading.spinkit.animation; 17 | 18 | import android.util.Property; 19 | 20 | /** 21 | * An implementation of {@link Property} to be used specifically with fields of type 22 | * int. This type-specific subclass enables performance benefit by allowing 23 | * calls to a {@link #set(Object, Integer) set()} function that takes the primitive 24 | * int type and avoids autoboxing and other overhead associated with the 25 | * Integer class. 26 | * 27 | * @param The class on which the Property is declared. 28 | */ 29 | public abstract class IntProperty extends Property { 30 | 31 | public IntProperty(String name) { 32 | super(Integer.class, name); 33 | } 34 | 35 | /** 36 | * A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing 37 | * with fields of type int. 38 | */ 39 | public abstract void setValue(T object, int value); 40 | 41 | @Override 42 | final public void set(T object, Integer value) { 43 | setValue(object, value); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/PathInterpolatorCompatApi21.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.superlht.htloading.spinkit.animation.interpolator; 18 | 19 | import android.annotation.TargetApi; 20 | import android.graphics.Path; 21 | import android.os.Build; 22 | import android.view.animation.Interpolator; 23 | import android.view.animation.PathInterpolator; 24 | 25 | /** 26 | * API 21+ implementation for path interpolator compatibility. 27 | */ 28 | class PathInterpolatorCompatApi21 { 29 | 30 | private PathInterpolatorCompatApi21() { 31 | // prevent instantiation 32 | } 33 | 34 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 35 | public static Interpolator create(Path path) { 36 | return new PathInterpolator(path); 37 | } 38 | 39 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 40 | public static Interpolator create(float controlX, float controlY) { 41 | return new PathInterpolator(controlX, controlY); 42 | } 43 | 44 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 45 | public static Interpolator create(float controlX1, float controlY1, 46 | float controlX2, float controlY2) { 47 | return new PathInterpolator(controlX1, controlY1, controlX2, controlY2); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /HTLoading/src/main/res/layout/loading_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 23 | 24 | 29 | 30 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 51 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/CubeGrid.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.RectSprite; 8 | import com.superlht.htloading.spinkit.sprite.Sprite; 9 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 10 | 11 | 12 | /** 13 | * Created by ybq. 14 | */ 15 | public class CubeGrid extends SpriteContainer { 16 | 17 | @Override 18 | public Sprite[] onCreateChild() { 19 | int delays[] = new int[]{ 20 | 200, 300, 400 21 | , 100, 200, 300 22 | , 0, 100, 200 23 | }; 24 | GridItem[] gridItems = new GridItem[9]; 25 | for (int i = 0; i < gridItems.length; i++) { 26 | gridItems[i] = new GridItem(); 27 | gridItems[i].setAnimationDelay(delays[i]); 28 | } 29 | return gridItems; 30 | } 31 | 32 | @Override 33 | protected void onBoundsChange(Rect bounds) { 34 | super.onBoundsChange(bounds); 35 | bounds = clipSquare(bounds); 36 | int width = (int) (bounds.width() * 0.33f); 37 | int height = (int) (bounds.height() * 0.33f); 38 | for (int i = 0; i < getChildCount(); i++) { 39 | int x = i % 3; 40 | int y = i / 3; 41 | int l = bounds.left + x * width; 42 | int t = bounds.top + y * height; 43 | Sprite sprite = getChildAt(i); 44 | sprite.setDrawBounds(l, t, l + width, t + height); 45 | } 46 | } 47 | 48 | private class GridItem extends RectSprite { 49 | @Override 50 | public ValueAnimator onCreateAnimation() { 51 | float fractions[] = new float[]{0f, 0.35f, 0.7f, 1f}; 52 | return new SpriteAnimatorBuilder(this). 53 | scale(fractions, 1f, 0f, 1f, 1f). 54 | duration(1300). 55 | easeInOut(fractions) 56 | .build(); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/ThreeBounce.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | 6 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 7 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 8 | import com.superlht.htloading.spinkit.sprite.Sprite; 9 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 10 | 11 | 12 | /** 13 | * Created by ybq. 14 | */ 15 | public class ThreeBounce extends SpriteContainer { 16 | 17 | @Override 18 | public Sprite[] onCreateChild() { 19 | return new Sprite[]{ 20 | new Bounce(), 21 | new Bounce(), 22 | new Bounce() 23 | }; 24 | } 25 | 26 | @Override 27 | public void onChildCreated(Sprite... sprites) { 28 | super.onChildCreated(sprites); 29 | sprites[1].setAnimationDelay(160); 30 | sprites[2].setAnimationDelay(320); 31 | } 32 | 33 | @Override 34 | protected void onBoundsChange(Rect bounds) { 35 | super.onBoundsChange(bounds); 36 | bounds = clipSquare(bounds); 37 | int radius = bounds.width() / 8; 38 | int top = bounds.centerY() - radius; 39 | int bottom = bounds.centerY() + radius; 40 | 41 | for (int i = 0; i < getChildCount(); i++) { 42 | int left = bounds.width() * i / 3 43 | + bounds.left; 44 | getChildAt(i).setDrawBounds( 45 | left, top, left + radius * 2, bottom 46 | ); 47 | } 48 | } 49 | 50 | private class Bounce extends CircleSprite { 51 | 52 | Bounce() { 53 | setScale(0f); 54 | } 55 | 56 | @Override 57 | public ValueAnimator onCreateAnimation() { 58 | float fractions[] = new float[]{0f, 0.4f, 0.8f, 1f}; 59 | return new SpriteAnimatorBuilder(this).scale(fractions, 0f, 1f, 0f, 0f). 60 | duration(1400). 61 | easeInOut(fractions) 62 | .build(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/Wave.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | import android.os.Build; 6 | 7 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 8 | import com.superlht.htloading.spinkit.sprite.RectSprite; 9 | import com.superlht.htloading.spinkit.sprite.Sprite; 10 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 11 | 12 | 13 | /** 14 | * Created by ybq. 15 | */ 16 | public class Wave extends SpriteContainer { 17 | 18 | @Override 19 | public Sprite[] onCreateChild() { 20 | WaveItem[] waveItems = new WaveItem[5]; 21 | for (int i = 0; i < waveItems.length; i++) { 22 | waveItems[i] = new WaveItem(); 23 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 24 | waveItems[i].setAnimationDelay(600 + i * 100); 25 | } else { 26 | waveItems[i].setAnimationDelay(-1200 + i * 100); 27 | } 28 | 29 | } 30 | return waveItems; 31 | } 32 | 33 | @Override 34 | protected void onBoundsChange(Rect bounds) { 35 | super.onBoundsChange(bounds); 36 | bounds = clipSquare(bounds); 37 | int rw = bounds.width() / getChildCount(); 38 | int width = bounds.width() / 5 * 3 / 5; 39 | for (int i = 0; i < getChildCount(); i++) { 40 | Sprite sprite = getChildAt(i); 41 | int l = bounds.left + i * rw + rw / 5; 42 | int r = l + width; 43 | sprite.setDrawBounds(l, bounds.top, r, bounds.bottom); 44 | } 45 | } 46 | 47 | private class WaveItem extends RectSprite { 48 | 49 | WaveItem() { 50 | setScaleY(0.4f); 51 | } 52 | 53 | @Override 54 | public ValueAnimator onCreateAnimation() { 55 | float fractions[] = new float[]{0f, 0.2f, 0.4f, 1f}; 56 | return new SpriteAnimatorBuilder(this).scaleY(fractions, 0.4f, 1f, 0.4f, 0.4f). 57 | duration(1200). 58 | easeInOut(fractions) 59 | .build(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/KeyFrameInterpolator.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.animation.interpolator; 2 | 3 | import android.animation.TimeInterpolator; 4 | import android.view.animation.Interpolator; 5 | 6 | /** 7 | * Created by ybq. 8 | */ 9 | public class KeyFrameInterpolator implements Interpolator { 10 | 11 | private TimeInterpolator interpolator; 12 | private float[] fractions; 13 | 14 | 15 | public static KeyFrameInterpolator easeInOut(float... fractions) { 16 | KeyFrameInterpolator interpolator = new KeyFrameInterpolator(Ease.inOut()); 17 | interpolator.setFractions(fractions); 18 | return interpolator; 19 | } 20 | 21 | public static KeyFrameInterpolator pathInterpolator(float controlX1, float controlY1, 22 | float controlX2, float controlY2, 23 | float... fractions) { 24 | KeyFrameInterpolator interpolator = new KeyFrameInterpolator(PathInterpolatorCompat.create(controlX1, controlY1, controlX2, controlY2)); 25 | interpolator.setFractions(fractions); 26 | return interpolator; 27 | } 28 | 29 | public KeyFrameInterpolator(TimeInterpolator interpolator, float... fractions) { 30 | this.interpolator = interpolator; 31 | this.fractions = fractions; 32 | } 33 | 34 | public void setFractions(float... fractions) { 35 | this.fractions = fractions; 36 | } 37 | 38 | @Override 39 | public synchronized float getInterpolation(float input) { 40 | if (fractions.length > 1) { 41 | for (int i = 0; i < fractions.length - 1; i++) { 42 | float start = fractions[i]; 43 | float end = fractions[i + 1]; 44 | float duration = end - start; 45 | if (input >= start && input <= end) { 46 | input = (input - start) / duration; 47 | return start + (interpolator.getInterpolation(input) 48 | * duration); 49 | } 50 | } 51 | } 52 | return interpolator.getInterpolation(input); 53 | } 54 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/manager/HTLoadingManager.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.manager 2 | 3 | import android.graphics.Color 4 | 5 | /** 6 | * Created by Hatim Liu on 2017/8/16. 7 | * loading全局统一配置 8 | */ 9 | 10 | class HTLoadingManager { 11 | companion object { 12 | internal var loadText: String = "正在加载" 13 | internal var successText: String = "加载成功" 14 | internal var failedText: String = "加载失败" 15 | internal var drawColor: Int = Color.WHITE 16 | internal var textSize: Float = 18f 17 | internal var isOpenAnim: Boolean = true 18 | internal var dialogSize: Int = 400 19 | internal var interceptBack: Boolean = true 20 | internal var dismissDelay: Long = 2000 21 | internal var isAutoDismiss: Boolean = true 22 | internal fun getManager(): HTLoadingManager.Companion { 23 | return this@Companion 24 | } 25 | 26 | fun isOpenAnim(boolean: Boolean): HTLoadingManager.Companion { 27 | isOpenAnim = boolean 28 | return this@Companion 29 | } 30 | 31 | fun textSize(size: Float): HTLoadingManager.Companion { 32 | textSize = size 33 | return this@Companion 34 | } 35 | 36 | fun failedText(string: String): HTLoadingManager.Companion { 37 | failedText = string 38 | return this@Companion 39 | } 40 | 41 | 42 | fun loadText(string: String): HTLoadingManager.Companion { 43 | loadText = string 44 | return this@Companion 45 | } 46 | 47 | fun successText(string: String): HTLoadingManager.Companion { 48 | successText = string 49 | return this@Companion 50 | } 51 | 52 | fun delay(time: Long): HTLoadingManager.Companion { 53 | dismissDelay = time 54 | return this@Companion 55 | } 56 | 57 | fun drawColor(color: Int): HTLoadingManager.Companion { 58 | drawColor = color 59 | return this@Companion 60 | } 61 | 62 | fun isAutoDismiss(boolean: Boolean): HTLoadingManager.Companion { 63 | isAutoDismiss = boolean 64 | return this@Companion 65 | } 66 | } 67 | 68 | 69 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/WanderingCubes.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | import android.os.Build; 6 | 7 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 8 | import com.superlht.htloading.spinkit.sprite.RectSprite; 9 | import com.superlht.htloading.spinkit.sprite.Sprite; 10 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 11 | 12 | 13 | /** 14 | * Created by ybq. 15 | */ 16 | public class WanderingCubes extends SpriteContainer { 17 | 18 | @Override 19 | public Sprite[] onCreateChild() { 20 | return new Sprite[]{ 21 | new Cube(0), 22 | new Cube(3) 23 | }; 24 | } 25 | 26 | @Override 27 | public void onChildCreated(Sprite... sprites) { 28 | super.onChildCreated(sprites); 29 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { 30 | sprites[1].setAnimationDelay(-900); 31 | } 32 | } 33 | 34 | @Override 35 | protected void onBoundsChange(Rect bounds) { 36 | bounds = clipSquare(bounds); 37 | super.onBoundsChange(bounds); 38 | for (int i = 0; i < getChildCount(); i++) { 39 | Sprite sprite = getChildAt(i); 40 | sprite.setDrawBounds( 41 | bounds.left, 42 | bounds.top, 43 | bounds.left + bounds.width() / 4, 44 | bounds.top + bounds.height() / 4 45 | ); 46 | } 47 | } 48 | 49 | private class Cube extends RectSprite { 50 | int startFrame; 51 | 52 | public Cube(int startFrame) { 53 | this.startFrame = startFrame; 54 | } 55 | 56 | @Override 57 | public ValueAnimator onCreateAnimation() { 58 | float fractions[] = new float[]{0f, 0.25f, 0.5f, 0.51f, 0.75f, 1f}; 59 | SpriteAnimatorBuilder builder = new SpriteAnimatorBuilder(this). 60 | rotate(fractions, 0, -90, -179, -180, -270, -360). 61 | translateXPercentage(fractions, 0f, 0.75f, 0.75f, 0.75f, 0f, 0f). 62 | translateYPercentage(fractions, 0f, 0f, 0.75f, 0.75f, 0.75f, 0f). 63 | scale(fractions, 1f, 0.5f, 1f, 1f, 0.5f, 1f). 64 | duration(1800). 65 | easeInOut(fractions); 66 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 67 | builder. 68 | startFrame(startFrame); 69 | } 70 | return builder.build(); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/ChasingDots.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Rect; 5 | import android.os.Build; 6 | import android.view.animation.LinearInterpolator; 7 | 8 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 9 | import com.superlht.htloading.spinkit.sprite.CircleSprite; 10 | import com.superlht.htloading.spinkit.sprite.Sprite; 11 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 12 | 13 | 14 | /** 15 | * Created by ybq. 16 | */ 17 | public class ChasingDots extends SpriteContainer { 18 | 19 | @Override 20 | public Sprite[] onCreateChild() { 21 | return new Sprite[]{ 22 | new Dot(), 23 | new Dot() 24 | }; 25 | } 26 | 27 | @Override 28 | public void onChildCreated(Sprite... sprites) { 29 | super.onChildCreated(sprites); 30 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 31 | sprites[1].setAnimationDelay(1000); 32 | } else { 33 | sprites[1].setAnimationDelay(-1000); 34 | } 35 | } 36 | 37 | @Override 38 | public ValueAnimator onCreateAnimation() { 39 | float fractions[] = new float[]{0f, 1f}; 40 | return new SpriteAnimatorBuilder(this). 41 | rotate(fractions, 0, 360). 42 | duration(2000). 43 | interpolator(new LinearInterpolator()). 44 | build(); 45 | } 46 | 47 | @Override 48 | protected void onBoundsChange(Rect bounds) { 49 | super.onBoundsChange(bounds); 50 | bounds = clipSquare(bounds); 51 | int drawW = (int) (bounds.width() * 0.6f); 52 | getChildAt(0).setDrawBounds( 53 | bounds.right - drawW, 54 | bounds.top, 55 | bounds.right 56 | , bounds.top + drawW 57 | ); 58 | getChildAt(1).setDrawBounds( 59 | bounds.right - drawW, 60 | bounds.bottom - drawW, 61 | bounds.right, 62 | bounds.bottom 63 | ); 64 | } 65 | 66 | private class Dot extends CircleSprite { 67 | 68 | Dot() { 69 | setScale(0f); 70 | } 71 | 72 | @Override 73 | public ValueAnimator onCreateAnimation() { 74 | float fractions[] = new float[]{0f, 0.5f, 1f}; 75 | return new SpriteAnimatorBuilder(this). 76 | scale(fractions, 0f, 1f, 0f). 77 | duration(2000). 78 | easeInOut(fractions) 79 | .build(); 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/view/LoadingView.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.view 2 | 3 | import android.animation.Animator 4 | import android.animation.AnimatorListenerAdapter 5 | import android.animation.ValueAnimator 6 | import android.content.Context 7 | import android.graphics.Canvas 8 | import android.graphics.Color 9 | import android.graphics.Paint 10 | import android.graphics.RectF 11 | import android.util.AttributeSet 12 | import android.view.animation.* 13 | 14 | 15 | /** 16 | * Created by Hatim Liu on 2017/8/16. 17 | */ 18 | class LoadingView(context: Context?, attrs: AttributeSet?) : BaseLoadingView(context, attrs) { 19 | private var startAngle = 0f 20 | private val mPaint: Paint = Paint() 21 | private val bgColor = Color.argb(100, 255, 255, 255) 22 | private val mPaint2: Paint = Paint() 23 | private var valueAnimator = ValueAnimator.ofFloat(0f, 1f) 24 | 25 | init { 26 | mPaint.isAntiAlias = true 27 | mPaint.style = Paint.Style.STROKE 28 | mPaint.color = bgColor 29 | mPaint.strokeWidth = 8f 30 | mPaint2.isAntiAlias = true 31 | mPaint2.style = Paint.Style.STROKE 32 | mPaint2.color = bgColor 33 | mPaint2.strokeWidth = 8f 34 | } 35 | 36 | 37 | override fun onDraw(canvas: Canvas) { 38 | super.onDraw(canvas) 39 | mPaint2.color = bgColor 40 | canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2 - mPadding, mPaint2) 41 | mPaint.color = color 42 | val rectF = RectF(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding) 43 | canvas.drawArc(rectF, startAngle, 100f, false, mPaint) 44 | } 45 | 46 | 47 | fun startAnim(speed: Long = 1000) { 48 | stopAnim() 49 | startViewAnim(0f, 1f, speed) 50 | } 51 | 52 | fun stopAnim() { 53 | clearAnimation() 54 | valueAnimator.repeatCount = 1 55 | valueAnimator.cancel() 56 | valueAnimator.end() 57 | } 58 | 59 | private fun startViewAnim(startF: Float, endF: Float, time: Long) { 60 | valueAnimator.duration = time 61 | valueAnimator.interpolator = LinearInterpolator() 62 | valueAnimator.repeatCount = ValueAnimator.INFINITE 63 | valueAnimator.repeatMode = ValueAnimator.RESTART 64 | 65 | valueAnimator.addUpdateListener({ valueAnimator -> 66 | val value = valueAnimator.animatedValue as Float 67 | startAngle = 360 * value 68 | 69 | invalidate() 70 | }) 71 | valueAnimator.addListener( 72 | object : AnimatorListenerAdapter() { 73 | override fun onAnimationEnd(animation: Animator?) { 74 | super.onAnimationEnd(animation) 75 | } 76 | } 77 | ) 78 | valueAnimator.start() 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/SpriteContainer.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | 7 | import com.superlht.htloading.spinkit.animation.AnimationUtils; 8 | 9 | 10 | /** 11 | * Created by ybq. 12 | */ 13 | @SuppressWarnings("WeakerAccess") 14 | public abstract class SpriteContainer extends Sprite { 15 | 16 | private Sprite[] sprites; 17 | 18 | private int color; 19 | 20 | public SpriteContainer() { 21 | sprites = onCreateChild(); 22 | initCallBack(); 23 | onChildCreated(sprites); 24 | } 25 | 26 | private void initCallBack() { 27 | if (sprites != null) { 28 | for (Sprite sprite : sprites) { 29 | sprite.setCallback(this); 30 | } 31 | } 32 | } 33 | 34 | public void onChildCreated(Sprite... sprites) { 35 | 36 | } 37 | 38 | public int getChildCount() { 39 | return sprites == null ? 0 : sprites.length; 40 | } 41 | 42 | public Sprite getChildAt(int index) { 43 | return sprites == null ? null : sprites[index]; 44 | } 45 | 46 | @Override 47 | public void setColor(int color) { 48 | this.color = color; 49 | for (int i = 0; i < getChildCount(); i++) { 50 | getChildAt(i).setColor(color); 51 | } 52 | } 53 | 54 | @Override 55 | public int getColor() { 56 | return color; 57 | } 58 | 59 | @Override 60 | public void draw(Canvas canvas) { 61 | super.draw(canvas); 62 | drawChild(canvas); 63 | } 64 | 65 | public void drawChild(Canvas canvas) { 66 | if (sprites != null) { 67 | for (Sprite sprite : sprites) { 68 | int count = canvas.save(); 69 | sprite.draw(canvas); 70 | canvas.restoreToCount(count); 71 | } 72 | } 73 | } 74 | 75 | @Override 76 | protected void drawSelf(Canvas canvas) { 77 | } 78 | 79 | @Override 80 | protected void onBoundsChange(Rect bounds) { 81 | super.onBoundsChange(bounds); 82 | for (Sprite sprite : sprites) { 83 | sprite.setBounds(bounds); 84 | } 85 | } 86 | 87 | @Override 88 | public void start() { 89 | super.start(); 90 | AnimationUtils.start(sprites); 91 | } 92 | 93 | @Override 94 | public void stop() { 95 | super.stop(); 96 | AnimationUtils.stop(sprites); 97 | } 98 | 99 | @Override 100 | public boolean isRunning() { 101 | return AnimationUtils.isRunning(sprites) || super.isRunning(); 102 | } 103 | 104 | public abstract Sprite[] onCreateChild(); 105 | 106 | @Override 107 | public ValueAnimator onCreateAnimation() { 108 | return null; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/SpriteFactory.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit; 2 | 3 | 4 | import com.superlht.htloading.spinkit.sprite.Sprite; 5 | import com.superlht.htloading.spinkit.style.ChasingDots; 6 | import com.superlht.htloading.spinkit.style.Circle; 7 | import com.superlht.htloading.spinkit.style.CubeGrid; 8 | import com.superlht.htloading.spinkit.style.DoubleBounce; 9 | import com.superlht.htloading.spinkit.style.FadingCircle; 10 | import com.superlht.htloading.spinkit.style.FoldingCube; 11 | import com.superlht.htloading.spinkit.style.MultiplePulse; 12 | import com.superlht.htloading.spinkit.style.MultiplePulseRing; 13 | import com.superlht.htloading.spinkit.style.Pulse; 14 | import com.superlht.htloading.spinkit.style.PulseRing; 15 | import com.superlht.htloading.spinkit.style.RotatingCircle; 16 | import com.superlht.htloading.spinkit.style.RotatingPlane; 17 | import com.superlht.htloading.spinkit.style.ThreeBounce; 18 | import com.superlht.htloading.spinkit.style.WanderingCubes; 19 | import com.superlht.htloading.spinkit.style.Wave; 20 | 21 | /** 22 | * Created by ybq. 23 | */ 24 | public class SpriteFactory { 25 | 26 | public static Sprite create(Style style) { 27 | Sprite sprite = null; 28 | switch (style) { 29 | case ROTATING_PLANE: 30 | sprite = new RotatingPlane(); 31 | break; 32 | case DOUBLE_BOUNCE: 33 | sprite = new DoubleBounce(); 34 | break; 35 | case WAVE: 36 | sprite = new Wave(); 37 | break; 38 | case WANDERING_CUBES: 39 | sprite = new WanderingCubes(); 40 | break; 41 | case PULSE: 42 | sprite = new Pulse(); 43 | break; 44 | case CHASING_DOTS: 45 | sprite = new ChasingDots(); 46 | break; 47 | case THREE_BOUNCE: 48 | sprite = new ThreeBounce(); 49 | break; 50 | case CIRCLE: 51 | sprite = new Circle(); 52 | break; 53 | case CUBE_GRID: 54 | sprite = new CubeGrid(); 55 | break; 56 | case FADING_CIRCLE: 57 | sprite = new FadingCircle(); 58 | break; 59 | case FOLDING_CUBE: 60 | sprite = new FoldingCube(); 61 | break; 62 | case ROTATING_CIRCLE: 63 | sprite = new RotatingCircle(); 64 | break; 65 | case MULTIPLE_PULSE: 66 | sprite = new MultiplePulse(); 67 | break; 68 | case PULSE_RING: 69 | sprite = new PulseRing(); 70 | break; 71 | case MULTIPLE_PULSE_RING: 72 | sprite = new MultiplePulseRing(); 73 | break; 74 | default: 75 | break; 76 | } 77 | return sprite; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # HTLoading 2 | 3 | > A Simple LoadingDialog For Android.Use Kotlin 4 | 5 | [中文文档](README.md) 6 | 7 | ## Function 8 | 9 | - 显示默认的加载窗口 10 | - 显示默认的加载成功/失败窗口 11 | - 自定义加载/成功/失败页面 12 | - 可以全局设置参数 13 | 14 | ## 效果 15 | 16 | ![](/img/Effect.gif) 17 | ![](/img/CustomView.gif) 18 | 19 | ## 基本使用 20 | 21 | 步骤1.将依赖添加到项目的bulid.gradle里: 22 | 23 | ```groovy 24 | implementation 'com.superlht:HTLoading:1.0.0' 25 | ``` 26 | 27 | ## 使用方法 28 | 29 | ### 显示默认动画 30 | 31 | 如果全部使用默认配置,需要显示Loading的地方只需要调用: 32 | 33 | ```kotlin 34 | HTLoading(this).show() 35 | ``` 36 | 37 | 需要设置展示的文字: 38 | 39 | ```kotlin 40 | HTLoading(this).setLoadingText("加载中...").show() 41 | ``` 42 | 43 | 加载成功: 44 | 45 | ```kotlin 46 | HTLoading(this).setSuccessText("加载成功!").showSuccess() 47 | ``` 48 | 49 | HTLoading支持链式调用,如HTLoading(this).setLoadingText("加载中...").setsetFailedText("加载失败").show(),调用show方法后不支持链式调用 50 | 51 | ### 显示自定义View 52 | 53 | ### 显示SpinKit动画 54 | 55 | ## API文档 56 | 57 | | fun(方法) | describe(描述) | 58 | | ---------------------------------------- | ------------------- | 59 | | show() | 显示默认的Loading Dialog | 60 | | showSuccess() | 显示默认的成功dialog | 61 | | showFailed() | 显示默认的失败dialog | 62 | | showCustomFailed() | 显示自定义的失败界面 | 63 | | showCustomSuccess() | 显示自定义的成功界面 | 64 | | showCustomLoading() | 显示自定义的加载界面 | 65 | | setSuccessView(view:View) | 设置自定义成功界面 | 66 | | setFailedView(view:View) | 设置自定义失败界面 | 67 | | setLoadingView(view:View) | 设置自定义加载界面 | 68 | | setOnDialogDismissListener(listener: OnDialogDismissListener) | 设置对话框消失的监听器 | 69 | 70 | ## 全局设置 71 | 72 | 有需要在全局都使用统一Loading样式或内容的,可以在Application中进行全局初始化设置,如: 73 | 74 | ```kotlin 75 | HTLoadingManager.loadText("正在加载...").successText("加载成功") 76 | ``` 77 | 78 | 目前支持全局设置的方法有: 79 | 80 | - textSize(size:Float) :字体尺寸 81 | - loadText() /failedText()/successText() :加载/失败/成功时显示的文字 82 | - delay(time:Long) :成功和失败显示后延迟多少毫秒(ms)消失 83 | - drawColor(color:Int) : 图形的颜色 84 | - isAutoDismiss(boolean:Boolean) : 成功/失败后Dialog是否自动消失 85 | 86 | ### 感谢 87 | 88 | [LoadingDialog-ForgetAll](https://github.com/ForgetAll/LoadingDialog) 89 | 90 | 有任何问题欢迎issue提出 91 | 92 | ## License 93 | 94 | ``` 95 | Licensed under the Apache License, Version 2.0 (the "License"); 96 | you may not use this file except in compliance with the License. 97 | You may obtain a copy of the License at 98 | 99 | http://www.apache.org/licenses/LICENSE-2.0 100 | 101 | Unless required by applicable law or agreed to in writing, software 102 | distributed under the License is distributed on an "AS IS" BASIS, 103 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 104 | See the License for the specific language governing permissions and 105 | limitations under the License. 106 | ``` -------------------------------------------------------------------------------- /HTLoading/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'com.github.dcendents.android-maven' 5 | apply plugin: 'com.jfrog.bintray' 6 | 7 | 8 | android { 9 | compileSdkVersion 26 10 | buildToolsVersion "26.0.1" 11 | 12 | defaultConfig { 13 | minSdkVersion 15 14 | targetSdkVersion 26 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | } 19 | sourceSets { 20 | main { 21 | java.srcDirs = [ 22 | 'src/main/kotlin' 23 | ] 24 | } 25 | } 26 | buildTypes { 27 | release { 28 | minifyEnabled false 29 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: 'libs', include: ['*.jar']) 36 | 37 | implementation 'com.android.support:appcompat-v7:26.0.2' 38 | implementation 'org.jetbrains.kotlin:kotlin-stdlib-jre7:1.1.4-3' 39 | } 40 | repositories { 41 | mavenCentral() 42 | } 43 | version = "1.0.1" 44 | 45 | def siteUrl = 'https://github.com/lhtdeg/HTLoading' // 项目主页。 46 | def gitUrl = 'git@github.com:lhtdeg/HTLoading.git' // Git仓库的url。 47 | 48 | group = "com.superlht" 49 | install { 50 | repositories.mavenInstaller { 51 | pom { 52 | project { 53 | packaging 'aar' 54 | name 'HTLoading' 55 | description 'A LoadingDialog for Android with Kotlin Language.' 56 | url siteUrl 57 | 58 | licenses { 59 | license { 60 | name 'The Apache Software License, Version 2.0' 61 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 62 | } 63 | } 64 | 65 | developers { 66 | developer { 67 | id 'lhtdeg' 68 | name 'HatimLiu' 69 | email '476183603@qq.com' 70 | } 71 | } 72 | 73 | scm { 74 | connection gitUrl 75 | developerConnection gitUrl 76 | url siteUrl 77 | } 78 | } 79 | } 80 | } 81 | } 82 | task sourcesJar(type: Jar) { 83 | from android.sourceSets.main.java.srcDirs 84 | classifier = 'sources' 85 | } 86 | task javadoc(type: Javadoc) { 87 | source = android.sourceSets.main.java.srcDirs 88 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 89 | failOnError false 90 | } 91 | task javadocJar(type: Jar, dependsOn: javadoc) { 92 | classifier = 'javadoc' 93 | from javadoc.destinationDir 94 | } 95 | artifacts { 96 | archives javadocJar 97 | archives sourcesJar 98 | } 99 | 100 | Properties properties = new Properties() 101 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 102 | bintray { 103 | user = properties.getProperty("bintray.user") // Bintray的用户名。 104 | key = properties.getProperty("bintray.apikey") // Bintray刚才保存的ApiKey。 105 | 106 | configurations = ['archives'] 107 | pkg { 108 | repo = "maven" 109 | name = "HTLoading" 110 | userOrg = 'lhtdeg' 111 | websiteUrl = siteUrl 112 | vcsUrl = gitUrl 113 | licenses = ["Apache-2.0"] 114 | publish = true 115 | } 116 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/view/SuccessView.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.view 2 | 3 | import android.animation.Animator 4 | import android.animation.AnimatorListenerAdapter 5 | import android.animation.ValueAnimator 6 | import android.content.Context 7 | import android.graphics.Canvas 8 | import android.graphics.Paint 9 | import android.graphics.RectF 10 | import android.util.AttributeSet 11 | import android.view.animation.LinearInterpolator 12 | import com.superlht.htloading.listener.DrawFinishListener 13 | 14 | /** 15 | * Created by Hatim Liu on 2017/8/16. 16 | */ 17 | class SuccessView(context: Context?, attrs: AttributeSet?) : BaseLoadingView(context, attrs) { 18 | private val mPaint: Paint = Paint() 19 | private var valueAnimator = ValueAnimator.ofFloat(0f, 2f) 20 | private var endAngle = 0f 21 | private val mGap = 15f //内部×与圆的距离 22 | private var progress = 0f 23 | private var listener: DrawFinishListener? = null 24 | 25 | 26 | init { 27 | mPaint.isAntiAlias = true 28 | mPaint.style = Paint.Style.STROKE 29 | mPaint.color = color 30 | mPaint.strokeWidth = 8f 31 | } 32 | 33 | override fun onDraw(canvas: Canvas) { 34 | super.onDraw(canvas) 35 | val rectF = RectF(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding) 36 | canvas.drawArc(rectF, 0f, endAngle, false, mPaint) 37 | if (progress in 1f..1.5f) { 38 | canvas.drawLine( 39 | mWidth / 4.7f, 40 | mWidth / 1.7f, 41 | (progress - 1f) * 2 * mWidth / 4 + mWidth / 4.7f, 42 | (progress - 1f) * 2 * mWidth / 4 + mWidth / 2 43 | , mPaint) 44 | } 45 | if (progress in 1.5f..2f) { 46 | canvas.drawLine( 47 | mWidth / 4.7f, 48 | mWidth / 1.7f, 49 | mWidth / 4 + mWidth / 4.7f, 50 | mWidth / 4 + mWidth / 2, 51 | mPaint) 52 | canvas.drawLine( 53 | mWidth / 4 + mWidth / 5, 54 | mWidth / 4 + mWidth / 2, 55 | mWidth / 4 + mWidth / 5 + (progress - 1.5f) * 2 * mWidth / 3, 56 | mWidth / 4 + mWidth / 2 - (progress - 1.5f) * 2 * mWidth / 3, 57 | mPaint) 58 | } 59 | 60 | } 61 | 62 | fun setOnDrawFinishListener(listener: DrawFinishListener) { 63 | this.listener = listener 64 | } 65 | 66 | fun startAnim(speed: Long = 1000) { 67 | stopAnim() 68 | startViewAnim(speed) 69 | } 70 | 71 | fun stopAnim() { 72 | clearAnimation() 73 | valueAnimator.repeatCount = 1 74 | valueAnimator.cancel() 75 | valueAnimator.end() 76 | } 77 | 78 | private fun startViewAnim(time: Long) { 79 | valueAnimator.duration = time 80 | valueAnimator.interpolator = LinearInterpolator() 81 | valueAnimator.repeatCount = 0 82 | 83 | valueAnimator.addUpdateListener({ valueAnimator -> 84 | val value = valueAnimator.animatedValue as Float 85 | endAngle = 360 * value 86 | progress = value 87 | invalidate() 88 | }) 89 | valueAnimator.addListener( 90 | object : AnimatorListenerAdapter() { 91 | override fun onAnimationEnd(animation: Animator?) { 92 | super.onAnimationEnd(animation) 93 | listener?.onDrawFinished(this@SuccessView) 94 | } 95 | } 96 | ) 97 | valueAnimator.start() 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/style/FoldingCube.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.style; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Rect; 6 | import android.os.Build; 7 | import android.view.animation.LinearInterpolator; 8 | 9 | import com.superlht.htloading.spinkit.animation.SpriteAnimatorBuilder; 10 | import com.superlht.htloading.spinkit.sprite.RectSprite; 11 | import com.superlht.htloading.spinkit.sprite.Sprite; 12 | import com.superlht.htloading.spinkit.sprite.SpriteContainer; 13 | 14 | 15 | /** 16 | * Created by ybq. 17 | */ 18 | public class FoldingCube extends SpriteContainer { 19 | 20 | @SuppressWarnings("FieldCanBeLocal") 21 | private boolean wrapContent = false; 22 | 23 | @Override 24 | public Sprite[] onCreateChild() { 25 | Cube[] cubes 26 | = new Cube[4]; 27 | for (int i = 0; i < cubes.length; i++) { 28 | cubes[i] = new Cube(); 29 | 30 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 31 | cubes[i].setAnimationDelay(300 * i); 32 | } else { 33 | cubes[i].setAnimationDelay(300 * i - 1200); 34 | } 35 | } 36 | return cubes; 37 | } 38 | 39 | @Override 40 | protected void onBoundsChange(Rect bounds) { 41 | super.onBoundsChange(bounds); 42 | bounds = clipSquare(bounds); 43 | int size = Math.min(bounds.width(), bounds.height()); 44 | if (wrapContent) { 45 | size = (int) Math.sqrt( 46 | (size 47 | * size) / 2); 48 | int oW = (bounds.width() - size) / 2; 49 | int oH = (bounds.height() - size) / 2; 50 | bounds = new Rect( 51 | bounds.left + oW, 52 | bounds.top + oH, 53 | bounds.right - oW, 54 | bounds.bottom - oH 55 | ); 56 | } 57 | 58 | int px = bounds.left + size / 2 + 1; 59 | int py = bounds.top + size / 2 + 1; 60 | for (int i = 0; i < getChildCount(); i++) { 61 | Sprite sprite = getChildAt(i); 62 | sprite.setDrawBounds( 63 | bounds.left, 64 | bounds.top, 65 | px, 66 | py 67 | ); 68 | sprite.setPivotX(sprite.getDrawBounds().right); 69 | sprite.setPivotY(sprite.getDrawBounds().bottom); 70 | } 71 | } 72 | 73 | @Override 74 | public void drawChild(Canvas canvas) { 75 | 76 | Rect bounds = clipSquare(getBounds()); 77 | for (int i = 0; i < getChildCount(); i++) { 78 | int count = canvas.save(); 79 | canvas.rotate(45 + i * 90, bounds.centerX(), bounds.centerY()); 80 | Sprite sprite = getChildAt(i); 81 | sprite.draw(canvas); 82 | canvas.restoreToCount(count); 83 | } 84 | } 85 | 86 | private class Cube extends RectSprite { 87 | 88 | Cube() { 89 | setAlpha(0); 90 | setRotateX(-180); 91 | } 92 | 93 | @Override 94 | public ValueAnimator onCreateAnimation() { 95 | float fractions[] = new float[]{0f, 0.1f, 0.25f, 0.75f, 0.9f, 1f}; 96 | return new SpriteAnimatorBuilder(this). 97 | alpha(fractions, 0, 0, 255, 255, 0, 0). 98 | rotateX(fractions, -180, -180, 0, 0, 0, 0). 99 | rotateY(fractions, 0, 0, 0, 0, 180, 180). 100 | duration(2400). 101 | interpolator(new LinearInterpolator()) 102 | .build(); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/SpinKitView.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Color; 7 | import android.graphics.drawable.Drawable; 8 | import android.os.Build; 9 | import android.util.AttributeSet; 10 | import android.view.View; 11 | import android.widget.ProgressBar; 12 | 13 | 14 | import com.superlht.htloading.R; 15 | 16 | import com.superlht.htloading.spinkit.sprite.Sprite; 17 | 18 | /** 19 | * Created by ybq. 20 | */ 21 | public class SpinKitView extends ProgressBar { 22 | 23 | private Style mStyle; 24 | private int mColor; 25 | private Sprite mSprite; 26 | 27 | public SpinKitView(Context context) { 28 | this(context, null); 29 | } 30 | 31 | public SpinKitView(Context context, AttributeSet attrs) { 32 | this(context, attrs, R.attr.SpinKitViewStyle); 33 | } 34 | 35 | public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr) { 36 | this(context, attrs, defStyleAttr, R.style.SpinKitView); 37 | } 38 | 39 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 40 | public SpinKitView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 41 | super(context, attrs, defStyleAttr, defStyleRes); 42 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpinKitView, defStyleAttr, 43 | defStyleRes); 44 | mStyle = Style.values()[a.getInt(R.styleable.SpinKitView_SpinKit_Style, 0)]; 45 | mColor = a.getColor(R.styleable.SpinKitView_SpinKit_Color, Color.WHITE); 46 | a.recycle(); 47 | init(); 48 | setIndeterminate(true); 49 | } 50 | 51 | private void init() { 52 | Sprite sprite = SpriteFactory.create(mStyle); 53 | setIndeterminateDrawable(sprite); 54 | } 55 | 56 | @Override 57 | public void setIndeterminateDrawable(Drawable d) { 58 | if (!(d instanceof Sprite)) { 59 | throw new IllegalArgumentException("this d must be instanceof Sprite"); 60 | } 61 | setIndeterminateDrawable((Sprite) d); 62 | } 63 | 64 | public void setIndeterminateDrawable(Sprite d) { 65 | super.setIndeterminateDrawable(d); 66 | mSprite = d; 67 | if (mSprite.getColor() == 0) { 68 | mSprite.setColor(mColor); 69 | } 70 | onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight()); 71 | if (getVisibility() == VISIBLE) { 72 | mSprite.start(); 73 | } 74 | } 75 | 76 | @Override 77 | public Sprite getIndeterminateDrawable() { 78 | return mSprite; 79 | } 80 | 81 | public void setColor(int color) { 82 | this.mColor = color; 83 | if (mSprite != null) { 84 | mSprite.setColor(color); 85 | } 86 | invalidate(); 87 | } 88 | 89 | @Override 90 | public void unscheduleDrawable(Drawable who) { 91 | super.unscheduleDrawable(who); 92 | if (who instanceof Sprite) { 93 | ((Sprite) who).stop(); 94 | } 95 | } 96 | 97 | @Override 98 | public void onWindowFocusChanged(boolean hasWindowFocus) { 99 | super.onWindowFocusChanged(hasWindowFocus); 100 | if (hasWindowFocus) { 101 | if (mSprite != null && getVisibility() == VISIBLE) { 102 | mSprite.start(); 103 | } 104 | } 105 | } 106 | 107 | @Override 108 | public void onScreenStateChanged(int screenState) { 109 | super.onScreenStateChanged(screenState); 110 | if (screenState == View.SCREEN_STATE_OFF) { 111 | if (mSprite != null) { 112 | mSprite.stop(); 113 | } 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/view/FailedView.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.view 2 | 3 | import android.animation.Animator 4 | import android.animation.AnimatorListenerAdapter 5 | import android.animation.ValueAnimator 6 | import android.content.Context 7 | import android.graphics.Canvas 8 | import android.graphics.Paint 9 | import android.graphics.RectF 10 | import android.util.AttributeSet 11 | import android.view.animation.LinearInterpolator 12 | import com.superlht.htloading.listener.DrawFinishListener 13 | import com.superlht.htloading.util.SizeUtil 14 | 15 | /** 16 | * Created by Hatim Liu on 2017/8/16. 17 | */ 18 | class FailedView(context: Context?, attrs: AttributeSet?) : BaseLoadingView(context, attrs) { 19 | private val mPaint: Paint = Paint() 20 | private var valueAnimator = ValueAnimator.ofFloat(0f, 2f) 21 | private var endAngle = 0f 22 | private val mGap = 15f //内部×与圆的距离 23 | private var progress = 0f 24 | private var listener: DrawFinishListener? = null 25 | 26 | 27 | init { 28 | mPaint.isAntiAlias = true 29 | mPaint.style = Paint.Style.STROKE 30 | mPaint.color = color 31 | mPaint.strokeWidth = 8f 32 | } 33 | 34 | 35 | override fun onDraw(canvas: Canvas) { 36 | super.onDraw(canvas) 37 | val rectF = RectF(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding) 38 | canvas.drawArc(rectF, 0f, endAngle, false, mPaint) 39 | if (progress in 1f..1.5f) { 40 | val mEnd = (mWidth - 2 * mPadding - 2 * SizeUtil.dip2px(context, mGap)) * (progress - 1f) * 2 41 | canvas.drawLine( 42 | mPadding + SizeUtil.dip2px(context, mGap), 43 | mPadding + SizeUtil.dip2px(context, mGap), 44 | mPadding + SizeUtil.dip2px(context, mGap) + mEnd, 45 | mPadding + SizeUtil.dip2px(context, mGap) + mEnd, mPaint) 46 | } 47 | if (progress in 1.5f..2f) { 48 | val mEnd = (mWidth - 2 * mPadding - 2 * SizeUtil.dip2px(context, mGap)) * (progress - 1.5f) * 2 49 | canvas.drawLine( 50 | mPadding + SizeUtil.dip2px(context, mGap), 51 | mPadding + SizeUtil.dip2px(context, mGap), 52 | mWidth - mPadding - SizeUtil.dip2px(context, mGap), 53 | mWidth - mPadding - SizeUtil.dip2px(context, mGap), mPaint) 54 | canvas.drawLine( 55 | mWidth - mPadding - SizeUtil.dip2px(context, mGap), 56 | mPadding + SizeUtil.dip2px(context, mGap), 57 | mWidth - mPadding - SizeUtil.dip2px(context, mGap) - mEnd, 58 | mPadding + SizeUtil.dip2px(context, mGap) + mEnd, 59 | mPaint) 60 | } 61 | 62 | } 63 | 64 | fun setOnDrawFinishListener(listener: DrawFinishListener) { 65 | this.listener = listener 66 | } 67 | 68 | fun startAnim(speed: Long = 1000) { 69 | stopAnim() 70 | startViewAnim(speed) 71 | } 72 | 73 | fun stopAnim() { 74 | clearAnimation() 75 | valueAnimator.repeatCount = 1 76 | valueAnimator.cancel() 77 | valueAnimator.end() 78 | } 79 | 80 | private fun startViewAnim(time: Long) { 81 | valueAnimator.duration = time 82 | valueAnimator.interpolator = LinearInterpolator() 83 | valueAnimator.repeatCount = 0 84 | 85 | valueAnimator.addUpdateListener({ valueAnimator -> 86 | val value = valueAnimator.animatedValue as Float 87 | endAngle = 360 * value 88 | progress = value 89 | invalidate() 90 | }) 91 | valueAnimator.addListener( 92 | object : AnimatorListenerAdapter() { 93 | override fun onAnimationEnd(animation: Animator?) { 94 | super.onAnimationEnd(animation) 95 | listener?.onDrawFinished(this@FailedView) 96 | } 97 | } 98 | ) 99 | valueAnimator.start() 100 | } 101 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HTLoading 2 | 3 | > 一个Android端简单易用的LoadingDialog,基于Kotlin语言 4 | 5 | [English Document](README-EN.md) 6 | 7 | ## 功能 8 | 9 | - 显示默认的加载窗口 10 | - 显示默认的加载成功/失败窗口 11 | - 自定义加载/成功/失败页面 12 | - 可以全局设置参数 13 | 14 | ## 效果 15 | 16 | 17 | 18 | 19 | 20 | ## 基本使用 21 | 22 | 步骤1.将依赖添加到项目的bulid.gradle里: 23 | 24 | Android Gradle plugin 3.0+ 25 | ```groovy 26 | implementation 'com.superlht:HTLoading:1.0.1' 27 | ``` 28 | else 29 | ```groovy 30 | compile 'com.superlht:HTLoading:1.0.1' 31 | ``` 32 | 33 | ## 使用方法 34 | 35 | ### 显示默认动画 36 | 37 | 如果全部使用默认配置,需要显示Loading的地方只需要调用: 38 | 39 | ```kotlin 40 | HTLoading(this).show() 41 | ``` 42 | 43 | 需要设置展示的文字: 44 | 45 | ```kotlin 46 | HTLoading(this).setLoadingText("加载中...").show() 47 | ``` 48 | 49 | 加载成功: 50 | 51 | ```kotlin 52 | HTLoading(this).setSuccessText("加载成功!").showSuccess() 53 | ``` 54 | 55 | HTLoading支持链式调用,如HTLoading(this).setLoadingText("加载中...").setsetFailedText("加载失败").show(),调用show方法后不支持链式调用 56 | 57 | ### 显示自定义View 58 | 59 | ### 显示SpinKit动画 60 | 61 | 62 | 63 | | Style | Preview | 64 | | -------------- | --------------------------- | 65 | | RotatingPlane | ![](img/RotatingPlane.gif) | 66 | | DoubleBounce | ![](img/DoubleBounce.gif) | 67 | | Wave | ![](img/Wave.gif) | 68 | | WanderingCubes | ![](img/WanderingCubes.gif) | 69 | | Pulse | ![](img/Pulse.gif) | 70 | | ChasingDots | ![](img/ChasingDots.gif) | 71 | | ThreeBounce | ![](img/ThreeBounce.gif) | 72 | | Circle | ![](img/Circle.gif) | 73 | | CubeGrid | ![](img/CubeGrid.gif) | 74 | | FadingCircle | ![](img/FadingCircle.gif) | 75 | | FoldingCube | ![](img/FoldingCube.gif) | 76 | | RotatingCircle | ![](img/RotatingCircle.gif) | 77 | 78 | ## 79 | 80 | ## API文档 81 | 82 | | fun(方法) | describe(描述) | 83 | | ---------------------------------------- | ------------------- | 84 | | show() | 显示默认的Loading Dialog | 85 | | showSuccess() | 显示默认的成功dialog | 86 | | showFailed() | 显示默认的失败dialog | 87 | | showCustomFailed() | 显示自定义的失败界面 | 88 | | showCustomSuccess() | 显示自定义的成功界面 | 89 | | showCustomLoading() | 显示自定义的加载界面 | 90 | | setSuccessView(view:View) | 设置自定义成功界面 | 91 | | setFailedView(view:View) | 设置自定义失败界面 | 92 | | setLoadingView(view:View) | 设置自定义加载界面 | 93 | | setOnDialogDismissListener(listener: OnDialogDismissListener) | 设置对话框消失的监听器 | 94 | 95 | ## 全局设置 96 | 97 | 有需要在全局都使用统一Loading样式或内容的,可以在Application中进行全局初始化设置,如: 98 | 99 | ```kotlin 100 | HTLoadingManager.loadText("正在加载...").successText("加载成功") 101 | ``` 102 | 103 | 目前支持全局设置的方法有: 104 | 105 | - textSize(size:Float) :字体尺寸 106 | - loadText() /failedText()/successText() :加载/失败/成功时显示的文字 107 | - delay(time:Long) :成功和失败显示后延迟多少毫秒(ms)消失 108 | - drawColor(color:Int) : 图形的颜色 109 | - isAutoDismiss(boolean:Boolean) : 成功/失败后Dialog是否自动消失 110 | 111 | ### 感谢 112 | 113 | [ForgetAll/LoadingDialog](https://github.com/ForgetAll/LoadingDialog) 114 | 115 | [ybq/Android-SpinKit](https://github.com/ybq/Android-SpinKit) 116 | 117 | 有任何问题欢迎issue提出 118 | 119 | ### [更新日志](CHANGELOG.md) 120 | 121 | ## License 122 | 123 | ``` 124 | Licensed under the Apache License, Version 2.0 (the "License"); 125 | you may not use this file except in compliance with the License. 126 | You may obtain a copy of the License at 127 | 128 | http://www.apache.org/licenses/LICENSE-2.0 129 | 130 | Unless required by applicable law or agreed to in writing, software 131 | distributed under the License is distributed on an "AS IS" BASIS, 132 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133 | See the License for the specific language governing permissions and 134 | limitations under the License. 135 | ``` -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/PathInterpolatorCompat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.superlht.htloading.spinkit.animation.interpolator; 18 | 19 | import android.graphics.Path; 20 | import android.os.Build; 21 | import android.view.animation.Interpolator; 22 | 23 | /** 24 | * Helper for creating path-based {@link Interpolator} instances. On API 21 or newer, the 25 | * platform implementation will be used and on older platforms a compatible alternative 26 | * implementation will be used. 27 | */ 28 | public class PathInterpolatorCompat { 29 | 30 | private PathInterpolatorCompat() { 31 | // prevent instantiation 32 | } 33 | 34 | /** 35 | * Create an {@link Interpolator} for an arbitrary {@link Path}. The {@link Path} 36 | * must begin at {@code (0, 0)} and end at {@code (1, 1)}. The x-coordinate along the 37 | * {@link Path} is the input value and the output is the y coordinate of the line at that 38 | * point. This means that the Path must conform to a function {@code y = f(x)}. 39 | *

40 | * The {@link Path} must not have gaps in the x direction and must not 41 | * loop back on itself such that there can be two points sharing the same x coordinate. 42 | * 43 | * @param path the {@link Path} to use to make the line representing the {@link Interpolator} 44 | * @return the {@link Interpolator} representing the {@link Path} 45 | */ 46 | @SuppressWarnings("unused") 47 | public static Interpolator create(Path path) { 48 | if (Build.VERSION.SDK_INT >= 21) { 49 | return PathInterpolatorCompatApi21.create(path); 50 | } 51 | return PathInterpolatorCompatBase.create(path); 52 | } 53 | 54 | /** 55 | * Create an {@link Interpolator} for a quadratic Bezier curve. The end points 56 | * {@code (0, 0)} and {@code (1, 1)} are assumed. 57 | * 58 | * @param controlX the x coordinate of the quadratic Bezier control point 59 | * @param controlY the y coordinate of the quadratic Bezier control point 60 | * @return the {@link Interpolator} representing the quadratic Bezier curve 61 | */ 62 | @SuppressWarnings("unused") 63 | public static Interpolator create(float controlX, float controlY) { 64 | if (Build.VERSION.SDK_INT >= 21) { 65 | return PathInterpolatorCompatApi21.create(controlX, controlY); 66 | } 67 | return PathInterpolatorCompatBase.create(controlX, controlY); 68 | } 69 | 70 | /** 71 | * Create an {@link Interpolator} for a cubic Bezier curve. The end points 72 | * {@code (0, 0)} and {@code (1, 1)} are assumed. 73 | * 74 | * @param controlX1 the x coordinate of the first control point of the cubic Bezier 75 | * @param controlY1 the y coordinate of the first control point of the cubic Bezier 76 | * @param controlX2 the x coordinate of the second control point of the cubic Bezier 77 | * @param controlY2 the y coordinate of the second control point of the cubic Bezier 78 | * @return the {@link Interpolator} representing the cubic Bezier curve 79 | */ 80 | public static Interpolator create(float controlX1, float controlY1, 81 | float controlX2, float controlY2) { 82 | if (Build.VERSION.SDK_INT >= 21) { 83 | return PathInterpolatorCompatApi21.create(controlX1, controlY1, controlX2, controlY2); 84 | } 85 | return PathInterpolatorCompatBase.create(controlX1, controlY1, controlX2, controlY2); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/interpolator/PathInterpolatorDonut.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.superlht.htloading.spinkit.animation.interpolator; 17 | 18 | import android.graphics.Path; 19 | import android.graphics.PathMeasure; 20 | import android.view.animation.Interpolator; 21 | 22 | /** 23 | * A path interpolator implementation compatible with API 4+. 24 | */ 25 | class PathInterpolatorDonut implements Interpolator { 26 | 27 | /** 28 | * Governs the accuracy of the approximation of the {@link Path}. 29 | */ 30 | private static final float PRECISION = 0.002f; 31 | 32 | private final float[] mX; 33 | private final float[] mY; 34 | 35 | public PathInterpolatorDonut(Path path) { 36 | final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */); 37 | 38 | final float pathLength = pathMeasure.getLength(); 39 | final int numPoints = (int) (pathLength / PRECISION) + 1; 40 | 41 | mX = new float[numPoints]; 42 | mY = new float[numPoints]; 43 | 44 | final float[] position = new float[2]; 45 | for (int i = 0; i < numPoints; ++i) { 46 | final float distance = (i * pathLength) / (numPoints - 1); 47 | pathMeasure.getPosTan(distance, position, null /* tangent */); 48 | 49 | mX[i] = position[0]; 50 | mY[i] = position[1]; 51 | } 52 | } 53 | 54 | public PathInterpolatorDonut(float controlX, float controlY) { 55 | this(createQuad(controlX, controlY)); 56 | } 57 | 58 | public PathInterpolatorDonut(float controlX1, float controlY1, 59 | float controlX2, float controlY2) { 60 | this(createCubic(controlX1, controlY1, controlX2, controlY2)); 61 | } 62 | 63 | @Override 64 | public float getInterpolation(float t) { 65 | if (t <= 0.0f) { 66 | return 0.0f; 67 | } else if (t >= 1.0f) { 68 | return 1.0f; 69 | } 70 | 71 | // Do a binary search for the correct x to interpolate between. 72 | int startIndex = 0; 73 | int endIndex = mX.length - 1; 74 | while (endIndex - startIndex > 1) { 75 | int midIndex = (startIndex + endIndex) / 2; 76 | if (t < mX[midIndex]) { 77 | endIndex = midIndex; 78 | } else { 79 | startIndex = midIndex; 80 | } 81 | } 82 | 83 | final float xRange = mX[endIndex] - mX[startIndex]; 84 | if (xRange == 0) { 85 | return mY[startIndex]; 86 | } 87 | 88 | final float tInRange = t - mX[startIndex]; 89 | final float fraction = tInRange / xRange; 90 | 91 | final float startY = mY[startIndex]; 92 | final float endY = mY[endIndex]; 93 | 94 | return startY + (fraction * (endY - startY)); 95 | } 96 | 97 | private static Path createQuad(float controlX, float controlY) { 98 | final Path path = new Path(); 99 | path.moveTo(0.0f, 0.0f); 100 | path.quadTo(controlX, controlY, 1.0f, 1.0f); 101 | return path; 102 | } 103 | 104 | private static Path createCubic(float controlX1, float controlY1, 105 | float controlX2, float controlY2) { 106 | final Path path = new Path(); 107 | path.moveTo(0.0f, 0.0f); 108 | path.cubicTo(controlX1, controlY1, controlX2, controlY2, 1.0f, 1.0f); 109 | return path; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 17 | 22 | 27 | 32 | 37 | 42 | 47 | 52 | 57 | 62 | 67 | 72 | 77 | 82 | 87 | 92 | 97 | 102 | 107 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /HTLoading/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 19 | 20 | 23 | 24 | 27 | 28 | 31 | 32 | 35 | 36 | 39 | 40 | 43 | 44 | 47 | 48 | 51 | 52 | 55 | 56 | 59 | 60 | 63 | 64 | 67 | 68 | 71 | 72 | 75 | 76 | 79 | 80 | 86 | 87 | 90 | 91 | 94 | 95 | 98 | 99 | 102 | 103 | 106 | 107 | 110 | 111 | 114 | 115 | 118 | 119 | 122 | 123 | 126 | 127 | 130 | 131 | 134 | 135 | 138 | 139 | 142 | 143 | 146 | 147 | 153 | 154 | 157 | 158 | 161 | 162 | 165 | 166 | 169 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 185 | 186 | 189 | 190 | 193 | 194 | 197 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 213 | 214 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/animation/SpriteAnimatorBuilder.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.animation; 2 | 3 | import android.animation.Keyframe; 4 | import android.animation.ObjectAnimator; 5 | import android.animation.PropertyValuesHolder; 6 | import android.util.Log; 7 | import android.util.Property; 8 | import android.view.animation.Animation; 9 | import android.view.animation.Interpolator; 10 | 11 | 12 | 13 | import java.util.HashMap; 14 | import java.util.Locale; 15 | import java.util.Map; 16 | 17 | import com.superlht.htloading.spinkit.animation.interpolator.KeyFrameInterpolator; 18 | import com.superlht.htloading.spinkit.sprite.Sprite; 19 | 20 | /** 21 | * Created by ybq. 22 | */ 23 | public class SpriteAnimatorBuilder { 24 | 25 | private static final String TAG = "SpriteAnimatorBuilder"; 26 | private Sprite sprite; 27 | private Interpolator interpolator; 28 | private int repeatCount = Animation.INFINITE; 29 | private long duration = 2000; 30 | private int startFrame = 0; 31 | private Map fds = new HashMap<>(); 32 | 33 | 34 | class FrameData { 35 | public FrameData(float[] fractions, Property property, T[] values) { 36 | this.fractions = fractions; 37 | this.property = property; 38 | this.values = values; 39 | } 40 | 41 | float[] fractions; 42 | Property property; 43 | T[] values; 44 | } 45 | 46 | class IntFrameData extends FrameData { 47 | 48 | public IntFrameData(float[] fractions, Property property, Integer[] values) { 49 | super(fractions, property, values); 50 | } 51 | } 52 | 53 | class FloatFrameData extends FrameData { 54 | 55 | public FloatFrameData(float[] fractions, Property property, Float[] values) { 56 | super(fractions, property, values); 57 | } 58 | } 59 | 60 | public SpriteAnimatorBuilder(Sprite sprite) { 61 | this.sprite = sprite; 62 | } 63 | 64 | public SpriteAnimatorBuilder scale(float fractions[], Float... scale) { 65 | holder(fractions, Sprite.SCALE, scale); 66 | return this; 67 | } 68 | 69 | public SpriteAnimatorBuilder alpha(float fractions[], Integer... alpha) { 70 | holder(fractions, Sprite.ALPHA, alpha); 71 | return this; 72 | } 73 | 74 | @SuppressWarnings("unused") 75 | public SpriteAnimatorBuilder scaleX(float fractions[], Float... scaleX) { 76 | holder(fractions, Sprite.SCALE, scaleX); 77 | return this; 78 | } 79 | 80 | public SpriteAnimatorBuilder scaleY(float fractions[], Float... scaleY) { 81 | holder(fractions, Sprite.SCALE_Y, scaleY); 82 | return this; 83 | } 84 | 85 | public SpriteAnimatorBuilder rotateX(float fractions[], Integer... rotateX) { 86 | holder(fractions, Sprite.ROTATE_X, rotateX); 87 | return this; 88 | } 89 | 90 | public SpriteAnimatorBuilder rotateY(float fractions[], Integer... rotateY) { 91 | holder(fractions, Sprite.ROTATE_Y, rotateY); 92 | return this; 93 | } 94 | 95 | @SuppressWarnings("unused") 96 | public SpriteAnimatorBuilder translateX(float fractions[], Integer... translateX) { 97 | holder(fractions, Sprite.TRANSLATE_X, translateX); 98 | return this; 99 | } 100 | 101 | 102 | @SuppressWarnings("unused") 103 | public SpriteAnimatorBuilder translateY(float fractions[], Integer... translateY) { 104 | holder(fractions, Sprite.TRANSLATE_Y, translateY); 105 | return this; 106 | } 107 | 108 | 109 | public SpriteAnimatorBuilder rotate(float fractions[], Integer... rotate) { 110 | holder(fractions, Sprite.ROTATE, rotate); 111 | return this; 112 | } 113 | 114 | public SpriteAnimatorBuilder translateXPercentage(float fractions[], Float... translateXPercentage) { 115 | holder(fractions, Sprite.TRANSLATE_X_PERCENTAGE, translateXPercentage); 116 | return this; 117 | } 118 | 119 | public SpriteAnimatorBuilder translateYPercentage(float[] fractions, Float... translateYPercentage) { 120 | holder(fractions, Sprite.TRANSLATE_Y_PERCENTAGE, translateYPercentage); 121 | return this; 122 | } 123 | 124 | private void holder(float[] fractions, Property property, Float[] values) { 125 | ensurePair(fractions.length, values.length); 126 | fds.put(property.getName(), new FloatFrameData(fractions, property, values)); 127 | } 128 | 129 | 130 | private void holder(float[] fractions, Property property, Integer[] values) { 131 | ensurePair(fractions.length, values.length); 132 | fds.put(property.getName(), new IntFrameData(fractions, property, values)); 133 | } 134 | 135 | private void ensurePair(int fractionsLength, int valuesLength) { 136 | if (fractionsLength != valuesLength) { 137 | throw new IllegalStateException(String.format( 138 | Locale.getDefault(), 139 | "The fractions.length must equal values.length, " + 140 | "fraction.length[%d], values.length[%d]", 141 | fractionsLength, 142 | valuesLength)); 143 | } 144 | } 145 | 146 | 147 | public SpriteAnimatorBuilder interpolator(Interpolator interpolator) { 148 | this.interpolator = interpolator; 149 | return this; 150 | } 151 | 152 | public SpriteAnimatorBuilder easeInOut(float... fractions) { 153 | interpolator(KeyFrameInterpolator.easeInOut( 154 | fractions 155 | )); 156 | return this; 157 | } 158 | 159 | 160 | public SpriteAnimatorBuilder duration(long duration) { 161 | this.duration = duration; 162 | return this; 163 | } 164 | 165 | @SuppressWarnings("unused") 166 | public SpriteAnimatorBuilder repeatCount(int repeatCount) { 167 | this.repeatCount = repeatCount; 168 | return this; 169 | } 170 | 171 | public SpriteAnimatorBuilder startFrame(int startFrame) { 172 | if (startFrame < 0) { 173 | Log.w(TAG, "startFrame should always be non-negative"); 174 | startFrame = 0; 175 | } 176 | this.startFrame = startFrame; 177 | return this; 178 | } 179 | 180 | public ObjectAnimator build() { 181 | 182 | PropertyValuesHolder[] holders = new PropertyValuesHolder[fds.size()]; 183 | int i = 0; 184 | for (Map.Entry fd : fds.entrySet()) { 185 | FrameData data = fd.getValue(); 186 | Keyframe[] keyframes = new Keyframe[data.fractions.length]; 187 | float[] fractions = data.fractions; 188 | float startF = fractions[startFrame]; 189 | for (int j = startFrame; j < (startFrame + data.values.length); j++) { 190 | int key = j - startFrame; 191 | int vk = j % data.values.length; 192 | float fraction = fractions[vk] - startF; 193 | if (fraction < 0) { 194 | fraction = fractions[fractions.length - 1] + fraction; 195 | } 196 | if (data instanceof IntFrameData) { 197 | keyframes[key] = Keyframe.ofInt(fraction, (Integer) data.values[vk]); 198 | } else if (data instanceof FloatFrameData) { 199 | keyframes[key] = Keyframe.ofFloat(fraction, (Float) data.values[vk]); 200 | } else { 201 | keyframes[key] = Keyframe.ofObject(fraction, data.values[vk]); 202 | } 203 | } 204 | holders[i] = PropertyValuesHolder.ofKeyframe(data.property, keyframes); 205 | i++; 206 | } 207 | 208 | ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(sprite, 209 | holders); 210 | animator.setDuration(duration); 211 | animator.setRepeatCount(repeatCount); 212 | animator.setInterpolator(interpolator); 213 | return animator; 214 | } 215 | 216 | } 217 | -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/view/HTLoading.kt: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.view 2 | 3 | import android.app.Dialog 4 | import android.content.Context 5 | import android.os.Handler 6 | import android.support.annotation.StyleRes 7 | import android.view.ContextThemeWrapper 8 | import android.view.Gravity 9 | import android.view.LayoutInflater 10 | import android.view.View 11 | import android.widget.LinearLayout 12 | import com.superlht.htloading.R 13 | import kotlinx.android.synthetic.main.loading_view.view.* 14 | import com.superlht.htloading.listener.DrawFinishListener 15 | import com.superlht.htloading.listener.OnDialogDismissListener 16 | import com.superlht.htloading.manager.HTLoadingManager 17 | import com.superlht.htloading.spinkit.SpinKitView 18 | import java.util.* 19 | 20 | 21 | /** 22 | * Created by Hatim Liu on 2017/8/16. 23 | */ 24 | class HTLoading(private val context: Context) : DrawFinishListener { 25 | 26 | private val manager = HTLoadingManager.getManager() 27 | 28 | private val view: View = LayoutInflater.from(context).inflate(R.layout.loading_view, null) 29 | 30 | private val viewList = ArrayList() 31 | 32 | private val loadingDialog = Dialog(context, R.style.loading_dialog) 33 | 34 | private var textSize: Float = manager.textSize 35 | 36 | private var loadingStr: String = manager.loadText 37 | 38 | private var successStr: String = manager.successText 39 | 40 | private var failedStr: String = manager.failedText 41 | 42 | private var interceptBack = true 43 | 44 | private var listener: OnDialogDismissListener? = null 45 | 46 | private var customSuccessView: View? = null 47 | 48 | private var customFailedView: View? = null 49 | 50 | private var customLoadingView: View? = null 51 | 52 | private var dismissDelay: Long = manager.dismissDelay 53 | 54 | private var drawColor: Int = manager.drawColor 55 | 56 | private var isAutoDismiss: Boolean = manager.isAutoDismiss 57 | 58 | 59 | init { 60 | viewList.add(view.loadingView) 61 | viewList.add(view.failedView) 62 | viewList.add(view.successView) 63 | viewList.add(view.customView) 64 | // viewList.add(com.superlht.htloading.view.spinKitView) 65 | view.failedView.setOnDrawFinishListener(this) 66 | view.successView.setOnDrawFinishListener(this) 67 | loadingDialog.setCancelable(!interceptBack) 68 | loadingDialog.setContentView(view.loading_dialog, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)) 69 | initStyle() 70 | } 71 | 72 | private fun initStyle() { 73 | // setSize(com.superlht.htloading.manager.dialogSize) 74 | setTextSize(manager.textSize) 75 | } 76 | 77 | fun show() { 78 | hideAll() 79 | view.loadingView.visibility = View.VISIBLE 80 | loadingDialog.show() 81 | view.text.text = loadingStr 82 | view.loadingView.startAnim(1000) 83 | } 84 | 85 | //显示自定义加载界面 86 | fun showCustomLoading() { 87 | hideAll() 88 | customLoadingView?.let { 89 | view.customView.removeAllViews() 90 | view.customView.visibility = View.VISIBLE 91 | view.customView.addView(it) 92 | loadingDialog.show() 93 | } 94 | } 95 | 96 | //显示自定义成功界面 97 | fun showCustomSuccess() { 98 | hideAll() 99 | customSuccessView?.let { 100 | view.customView.removeAllViews() 101 | view.customView.visibility = View.VISIBLE 102 | view.customView.addView(it) 103 | loadingDialog.show() 104 | onDrawFinished(it) 105 | } 106 | } 107 | 108 | //显示自定义失败界面 109 | fun showCustomFailed() { 110 | hideAll() 111 | customFailedView?.let { 112 | view.customView.removeAllViews() 113 | view.customView.visibility = View.VISIBLE 114 | view.customView.addView(it) 115 | loadingDialog.show() 116 | onDrawFinished(it) 117 | } 118 | } 119 | 120 | //设置自定义成功界面 121 | fun setSuccessView(view: View): HTLoading { 122 | customSuccessView = view 123 | return this 124 | } 125 | 126 | //设置自定义失败界面 127 | fun setFailedView(view: View): HTLoading { 128 | customFailedView = view 129 | return this 130 | } 131 | 132 | //设置自定义加载界面 133 | fun setLoadingView(view: View): HTLoading { 134 | customLoadingView = view 135 | return this 136 | } 137 | 138 | //当Dialog消失时的回调 139 | fun setOnDialogDismissListener(listener: OnDialogDismissListener) { 140 | this.listener = listener 141 | } 142 | 143 | fun setLoadingText(string: String): HTLoading { 144 | loadingStr = string 145 | return this 146 | } 147 | 148 | fun setSuccessText(string: String): HTLoading { 149 | successStr = string 150 | return this 151 | } 152 | 153 | fun setFailedText(string: String): HTLoading { 154 | failedStr = string 155 | return this 156 | } 157 | 158 | fun setIsAutoDismiss(boolean: Boolean): HTLoading { 159 | isAutoDismiss = boolean 160 | return this 161 | } 162 | 163 | fun showSpinKit(@StyleRes style: Int) { 164 | hideAll() 165 | val spinView = SpinKitView(ContextThemeWrapper(context, style)) 166 | spinView?.let { 167 | view.customView.removeAllViews() 168 | view.customView.visibility = View.VISIBLE 169 | view.customView.addView(it) 170 | } 171 | view.text.visibility = View.GONE 172 | loadingDialog.show() 173 | } 174 | 175 | fun showSuccess() { 176 | hideAll() 177 | view.successView.visibility = View.VISIBLE 178 | loadingDialog.show() 179 | view.text.text = successStr 180 | view.successView.startAnim() 181 | } 182 | 183 | fun showFailed() { 184 | hideAll() 185 | view.failedView.visibility = View.VISIBLE 186 | loadingDialog.show() 187 | view.text.text = failedStr 188 | view.failedView.startAnim() 189 | } 190 | 191 | fun setInterceptBack(boolean: Boolean): HTLoading { 192 | interceptBack = boolean 193 | loadingDialog.setCancelable(!interceptBack) 194 | return this 195 | } 196 | 197 | fun setTextSize(size: Float): HTLoading { 198 | textSize = size 199 | view.text.textSize = textSize 200 | return this 201 | } 202 | 203 | fun setCustomViewSize(size: Int): HTLoading { 204 | view.customView.layoutParams = LinearLayout.LayoutParams(size, size) 205 | return this 206 | } 207 | 208 | fun setDialogBackground(color: Int): HTLoading { 209 | view.loading_dialog.setBackgroundColor(color) 210 | return this 211 | } 212 | 213 | fun setSize(size: Int): HTLoading { 214 | setSize(size, size) 215 | return this 216 | } 217 | 218 | fun setDrawColor(color: Int): HTLoading { 219 | drawColor = color 220 | viewList 221 | .filterIsInstance() 222 | .forEach { it.setDrawColor(color) } 223 | return this 224 | } 225 | 226 | fun setSize(width: Int, height: Int): HTLoading { 227 | loadingDialog.window.setGravity(Gravity.CENTER) 228 | val lp = loadingDialog.window.attributes 229 | lp.width = width 230 | lp.height = height 231 | loadingDialog.window.attributes = lp 232 | loadingDialog.setContentView(view.loading_dialog, LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)) 233 | // com.superlht.htloading.view.loadingView.layoutParams.height = height 234 | // com.superlht.htloading.view.loadingView.layoutParams.width = width 235 | return this 236 | } 237 | 238 | 239 | private fun hideAll() { 240 | view.text.visibility = View.VISIBLE 241 | for (view in viewList) { 242 | view.visibility = View.GONE 243 | } 244 | } 245 | 246 | fun dismiss() { 247 | hideAll() 248 | loadingDialog.hide() 249 | listener?.dialogDismiss() 250 | } 251 | 252 | //动画加载完成时的回调 253 | override fun onDrawFinished(view: View) { 254 | if (isAutoDismiss) 255 | Handler().postDelayed({ 256 | dismiss() 257 | }, dismissDelay) 258 | } 259 | 260 | } -------------------------------------------------------------------------------- /HTLoading/src/main/kotlin/com/superlht/htloading/spinkit/sprite/Sprite.java: -------------------------------------------------------------------------------- 1 | package com.superlht.htloading.spinkit.sprite; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.annotation.SuppressLint; 5 | import android.graphics.Camera; 6 | import android.graphics.Canvas; 7 | import android.graphics.ColorFilter; 8 | import android.graphics.Matrix; 9 | import android.graphics.PixelFormat; 10 | import android.graphics.Rect; 11 | import android.graphics.drawable.Animatable; 12 | import android.graphics.drawable.Drawable; 13 | import android.util.Property; 14 | 15 | import com.superlht.htloading.spinkit.animation.AnimationUtils; 16 | import com.superlht.htloading.spinkit.animation.FloatProperty; 17 | import com.superlht.htloading.spinkit.animation.IntProperty; 18 | 19 | 20 | /** 21 | * Created by ybq. 22 | */ 23 | @SuppressWarnings("WeakerAccess") 24 | public abstract class Sprite extends Drawable implements 25 | ValueAnimator.AnimatorUpdateListener 26 | , Animatable 27 | , Drawable.Callback { 28 | 29 | private float scale = 1; 30 | private float scaleX = 1; 31 | private float scaleY = 1; 32 | private float pivotX; 33 | private float pivotY; 34 | private int animationDelay; 35 | private int rotateX; 36 | private int rotateY; 37 | private int translateX; 38 | private int translateY; 39 | private int rotate; 40 | private float translateXPercentage; 41 | private float translateYPercentage; 42 | private ValueAnimator animator; 43 | private int alpha = 255; 44 | private static final Rect ZERO_BOUNDS_RECT = new Rect(); 45 | protected Rect drawBounds = ZERO_BOUNDS_RECT; 46 | private Camera mCamera; 47 | private Matrix mMatrix; 48 | 49 | public Sprite() { 50 | mCamera = new Camera(); 51 | mMatrix = new Matrix(); 52 | } 53 | 54 | public abstract int getColor(); 55 | 56 | public abstract void setColor(int color); 57 | 58 | @Override 59 | public void setAlpha(int alpha) { 60 | this.alpha = alpha; 61 | } 62 | 63 | @Override 64 | public int getAlpha() { 65 | return alpha; 66 | } 67 | 68 | @SuppressLint("WrongConstant") 69 | @Override 70 | public int getOpacity() { 71 | return PixelFormat.RGBA_8888; 72 | } 73 | 74 | public float getTranslateXPercentage() { 75 | return translateXPercentage; 76 | } 77 | 78 | public void setTranslateXPercentage(float translateXPercentage) { 79 | this.translateXPercentage = translateXPercentage; 80 | } 81 | 82 | public float getTranslateYPercentage() { 83 | return translateYPercentage; 84 | } 85 | 86 | public void setTranslateYPercentage(float translateYPercentage) { 87 | this.translateYPercentage = translateYPercentage; 88 | } 89 | 90 | public int getTranslateX() { 91 | return translateX; 92 | } 93 | 94 | public void setTranslateX(int translateX) { 95 | this.translateX = translateX; 96 | } 97 | 98 | public int getTranslateY() { 99 | return translateY; 100 | } 101 | 102 | public void setTranslateY(int translateY) { 103 | this.translateY = translateY; 104 | } 105 | 106 | public int getRotate() { 107 | return rotate; 108 | } 109 | 110 | public void setRotate(int rotate) { 111 | this.rotate = rotate; 112 | } 113 | 114 | public float getScale() { 115 | return scale; 116 | } 117 | 118 | public void setScale(float scale) { 119 | this.scale = scale; 120 | setScaleX(scale); 121 | setScaleY(scale); 122 | } 123 | 124 | public float getScaleX() { 125 | return scaleX; 126 | } 127 | 128 | public void setScaleX(float scaleX) { 129 | this.scaleX = scaleX; 130 | } 131 | 132 | public float getScaleY() { 133 | return scaleY; 134 | } 135 | 136 | public void setScaleY(float scaleY) { 137 | this.scaleY = scaleY; 138 | } 139 | 140 | public int getRotateX() { 141 | return rotateX; 142 | } 143 | 144 | public void setRotateX(int rotateX) { 145 | this.rotateX = rotateX; 146 | } 147 | 148 | public int getRotateY() { 149 | return rotateY; 150 | } 151 | 152 | public void setRotateY(int rotateY) { 153 | this.rotateY = rotateY; 154 | } 155 | 156 | public float getPivotX() { 157 | return pivotX; 158 | } 159 | 160 | public void setPivotX(float pivotX) { 161 | this.pivotX = pivotX; 162 | } 163 | 164 | public float getPivotY() { 165 | return pivotY; 166 | } 167 | 168 | public void setPivotY(float pivotY) { 169 | this.pivotY = pivotY; 170 | } 171 | 172 | @SuppressWarnings("unused") 173 | public int getAnimationDelay() { 174 | return animationDelay; 175 | } 176 | 177 | public Sprite setAnimationDelay(int animationDelay) { 178 | this.animationDelay = animationDelay; 179 | return this; 180 | } 181 | 182 | @Override 183 | public void setColorFilter(ColorFilter colorFilter) { 184 | 185 | } 186 | 187 | public abstract ValueAnimator onCreateAnimation(); 188 | 189 | @Override 190 | public void start() { 191 | if (AnimationUtils.isStarted(animator)) { 192 | return; 193 | } 194 | 195 | animator = obtainAnimation(); 196 | if (animator == null) { 197 | return; 198 | } 199 | 200 | AnimationUtils.start(animator); 201 | invalidateSelf(); 202 | } 203 | 204 | public ValueAnimator obtainAnimation() { 205 | if (animator == null) { 206 | animator = onCreateAnimation(); 207 | } 208 | if (animator != null) { 209 | animator.addUpdateListener(this); 210 | animator.setStartDelay(animationDelay); 211 | } 212 | return animator; 213 | } 214 | 215 | @Override 216 | public void stop() { 217 | if (AnimationUtils.isStarted(animator)) { 218 | animator.removeAllUpdateListeners(); 219 | animator.end(); 220 | reset(); 221 | } 222 | } 223 | 224 | protected abstract void drawSelf(Canvas canvas); 225 | 226 | public void reset() { 227 | scale = 1; 228 | rotateX = 0; 229 | rotateY = 0; 230 | translateX = 0; 231 | translateY = 0; 232 | rotate = 0; 233 | translateXPercentage = 0f; 234 | translateYPercentage = 0f; 235 | } 236 | 237 | @Override 238 | public boolean isRunning() { 239 | return AnimationUtils.isRunning(animator); 240 | } 241 | 242 | @Override 243 | protected void onBoundsChange(Rect bounds) { 244 | super.onBoundsChange(bounds); 245 | setDrawBounds(bounds); 246 | } 247 | 248 | public void setDrawBounds(Rect drawBounds) { 249 | setDrawBounds(drawBounds.left, drawBounds.top, drawBounds.right, drawBounds.bottom); 250 | } 251 | 252 | public void setDrawBounds(int left, int top, int right, int bottom) { 253 | this.drawBounds = new Rect(left, top, right, bottom); 254 | setPivotX(getDrawBounds().centerX()); 255 | setPivotY(getDrawBounds().centerY()); 256 | } 257 | 258 | @Override 259 | public void invalidateDrawable(Drawable who) { 260 | invalidateSelf(); 261 | } 262 | 263 | @Override 264 | public void scheduleDrawable(Drawable who, Runnable what, long when) { 265 | 266 | } 267 | 268 | @Override 269 | public void unscheduleDrawable(Drawable who, Runnable what) { 270 | 271 | } 272 | 273 | @Override 274 | public void onAnimationUpdate(ValueAnimator animation) { 275 | final Callback callback = getCallback(); 276 | if (callback != null) { 277 | callback.invalidateDrawable(this); 278 | } 279 | } 280 | 281 | public Rect getDrawBounds() { 282 | return drawBounds; 283 | } 284 | 285 | @Override 286 | public void draw(Canvas canvas) { 287 | int tx = getTranslateX(); 288 | tx = tx == 0 ? (int) (getBounds().width() * getTranslateXPercentage()) : tx; 289 | int ty = getTranslateY(); 290 | ty = ty == 0 ? (int) (getBounds().height() * getTranslateYPercentage()) : ty; 291 | canvas.translate(tx, ty); 292 | canvas.scale(getScaleX(), getScaleY(), getPivotX(), getPivotY()); 293 | canvas.rotate(getRotate(), getPivotX(), getPivotY()); 294 | 295 | if (getRotateX() != 0 || getRotateY() != 0) { 296 | mCamera.save(); 297 | mCamera.rotateX(getRotateX()); 298 | mCamera.rotateY(getRotateY()); 299 | mCamera.getMatrix(mMatrix); 300 | mMatrix.preTranslate(-getPivotX(), -getPivotY()); 301 | mMatrix.postTranslate(getPivotX(), getPivotY()); 302 | mCamera.restore(); 303 | canvas.concat(mMatrix); 304 | } 305 | drawSelf(canvas); 306 | } 307 | 308 | public Rect clipSquare(Rect rect) { 309 | int w = rect.width(); 310 | int h = rect.height(); 311 | int min = Math.min(w, h); 312 | int cx = rect.centerX(); 313 | int cy = rect.centerY(); 314 | int r = min / 2; 315 | return new Rect( 316 | cx - r, 317 | cy - r, 318 | cx + r, 319 | cy + r 320 | ); 321 | } 322 | 323 | public static final Property ROTATE_X = new IntProperty("rotateX") { 324 | @Override 325 | public void setValue(Sprite object, int value) { 326 | object.setRotateX(value); 327 | } 328 | 329 | @Override 330 | public Integer get(Sprite object) { 331 | return object.getRotateX(); 332 | } 333 | }; 334 | 335 | public static final Property ROTATE = new IntProperty("rotate") { 336 | @Override 337 | public void setValue(Sprite object, int value) { 338 | object.setRotate(value); 339 | } 340 | 341 | @Override 342 | public Integer get(Sprite object) { 343 | return object.getRotate(); 344 | } 345 | }; 346 | 347 | public static final Property ROTATE_Y = new IntProperty("rotateY") { 348 | @Override 349 | public void setValue(Sprite object, int value) { 350 | object.setRotateY(value); 351 | } 352 | 353 | @Override 354 | public Integer get(Sprite object) { 355 | return object.getRotateY(); 356 | } 357 | }; 358 | 359 | @SuppressWarnings("unused") 360 | public static final Property TRANSLATE_X = new IntProperty("translateX") { 361 | @Override 362 | public void setValue(Sprite object, int value) { 363 | object.setTranslateX(value); 364 | } 365 | 366 | @Override 367 | public Integer get(Sprite object) { 368 | return object.getTranslateX(); 369 | } 370 | }; 371 | 372 | @SuppressWarnings("unused") 373 | public static final Property TRANSLATE_Y = new IntProperty("translateY") { 374 | @Override 375 | public void setValue(Sprite object, int value) { 376 | object.setTranslateY(value); 377 | } 378 | 379 | @Override 380 | public Integer get(Sprite object) { 381 | return object.getTranslateY(); 382 | } 383 | }; 384 | 385 | public static final Property TRANSLATE_X_PERCENTAGE = new FloatProperty("translateXPercentage") { 386 | @Override 387 | public void setValue(Sprite object, float value) { 388 | object.setTranslateXPercentage(value); 389 | } 390 | 391 | @Override 392 | public Float get(Sprite object) { 393 | return object.getTranslateXPercentage(); 394 | } 395 | }; 396 | 397 | public static final Property TRANSLATE_Y_PERCENTAGE = new FloatProperty("translateYPercentage") { 398 | @Override 399 | public void setValue(Sprite object, float value) { 400 | object.setTranslateYPercentage(value); 401 | } 402 | 403 | @Override 404 | public Float get(Sprite object) { 405 | return object.getTranslateYPercentage(); 406 | } 407 | }; 408 | 409 | @SuppressWarnings("unused") 410 | public static final Property SCALE_X = new FloatProperty("scaleX") { 411 | @Override 412 | public void setValue(Sprite object, float value) { 413 | object.setScaleX(value); 414 | } 415 | 416 | @Override 417 | public Float get(Sprite object) { 418 | return object.getScaleX(); 419 | } 420 | }; 421 | 422 | public static final Property SCALE_Y = new FloatProperty("scaleY") { 423 | @Override 424 | public void setValue(Sprite object, float value) { 425 | object.setScaleY(value); 426 | } 427 | 428 | @Override 429 | public Float get(Sprite object) { 430 | return object.getScaleY(); 431 | } 432 | }; 433 | 434 | public static final Property SCALE = new FloatProperty("scale") { 435 | @Override 436 | public void setValue(Sprite object, float value) { 437 | object.setScale(value); 438 | } 439 | 440 | @Override 441 | public Float get(Sprite object) { 442 | return object.getScale(); 443 | } 444 | }; 445 | 446 | public static final Property ALPHA = new IntProperty("alpha") { 447 | @Override 448 | public void setValue(Sprite object, int value) { 449 | object.setAlpha(value); 450 | } 451 | 452 | @Override 453 | public Integer get(Sprite object) { 454 | return object.getAlpha(); 455 | } 456 | }; 457 | 458 | } 459 | -------------------------------------------------------------------------------- /sample/src/main/assets/9squares-AlBoardman.json: -------------------------------------------------------------------------------- 1 | {"assets":[],"layers":[{"ddd":0,"ind":0,"ty":3,"nm":"NULL CONTROL 2","parent":20,"ks":{"o":{"k":0},"r":{"k":[{"i":{"x":[0.38],"y":[1]},"o":{"x":[0.194],"y":[0]},"n":["0p38_1_0p194_0"],"t":127.2,"s":[0],"e":[180]},{"t":158.4001953125}]},"p":{"k":[{"i":{"x":0,"y":1},"o":{"x":0.013,"y":0},"n":"0_1_0p013_0","t":24,"s":[417.9,540,0],"e":[340.2,540,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.1,"y":0.1},"n":"0p2_0p2_0p1_0p1","t":60,"s":[340.2,540,0],"e":[340.2,540,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.05,"y":0},"n":"0_1_0p05_0","t":127.2,"s":[340.2,540,0],"e":[538.514,540,0],"to":[0,0,0],"ti":[0,0,0]},{"t":158.4001953125}]},"a":{"k":[60,60,0]},"s":{"k":[74,74,100]}},"ao":0,"ip":0,"op":178,"st":-22.8,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Group 10","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":3,"s":[223.64,60,0],"e":[224.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.611,"y":0.611},"o":{"x":0.167,"y":0.167},"n":"0p611_0p611_0p167_0p167","t":22.8,"s":[224.992,60,0],"e":[224.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.061,"y":1},"o":{"x":0.167,"y":0},"n":"0p061_1_0p167_0","t":127.2,"s":[224.992,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.200390625}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-34,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-16.6,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":1,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":18.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":36,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":53.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":71,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":88.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":106,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":123.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":141,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":158.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":176,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":193.4,"s":[100,100,100],"e":[90,90,100]},{"t":211.0001953125}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-246.859],[246.859,0],[0,246.859],[-246.859,0]],"o":[[0,246.859],[-246.859,0],[0,-246.859],[246.859,0]],"v":[[446.978,0],[0,446.978],[-446.977,0],[0,-446.978]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10"}],"ip":0,"op":178,"st":-13.2,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Group 11","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":21.6,"s":[224.991,60,0],"e":[181.494,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":68.4,"s":[181.494,60,0],"e":[181.494,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[181.494,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.199609375}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":0,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":17.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":35,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":52.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":70,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":87.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":105,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":122.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":140,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":157.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":175,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":192.4,"s":[100,100,100],"e":[90,90,100]},{"t":210.000390625}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-222.836],[222.836,0],[0,222.836],[-222.836,0]],"o":[[0,222.836],[-222.836,0],[0,-222.836],[222.836,0]],"v":[[403.48,0],[0,403.48],[-403.48,0],[0,-403.48]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11"}],"ip":0,"op":178,"st":-14.4,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Group 12","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":20.4,"s":[224.992,60,0],"e":[139.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":67.2,"s":[139.496,60,0],"e":[139.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[139.496,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.1998046875}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-1,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":16.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":34,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":51.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":69,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":86.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":104,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":121.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":139,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":156.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":174,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":191.399,"s":[100,100,100],"e":[90,90,100]},{"t":208.999609375}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-199.641],[199.641,0],[0,199.641],[-199.641,0]],"o":[[0,199.641],[-199.641,0],[0,-199.641],[199.641,0]],"v":[[361.482,0],[0,361.482],[-361.482,0],[0,-361.482]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12"}],"ip":0,"op":178,"st":-15.6,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Group 13","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":19.2,"s":[224.992,60,0],"e":[97.498,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":66,"s":[97.498,60,0],"e":[97.498,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[97.498,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-2,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":15.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":33,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":50.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":68,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":85.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":103,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":120.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":138,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":155.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":173,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":190.399,"s":[100,100,100],"e":[90,90,100]},{"t":207.9998046875}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-176.446],[176.446,0],[0,176.446],[-176.446,0]],"o":[[0,176.446],[-176.446,0],[0,-176.446],[176.446,0]],"v":[[319.484,0],[0,319.484],[-319.484,0],[0,-319.484]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13"}],"ip":0,"op":178,"st":-16.8,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Group 14","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":18,"s":[224.992,60,0],"e":[55.5,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":64.8,"s":[55.5,60,0],"e":[55.5,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[55.5,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2001953125}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-3,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":14.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":32,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":49.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":67,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":84.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":102,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":119.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":137,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":154.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":172,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":189.399,"s":[100,100,100],"e":[90,90,100]},{"t":207}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-153.251],[153.251,0],[0,153.251],[-153.251,0]],"o":[[0,153.251],[-153.251,0],[0,-153.251],[153.251,0]],"v":[[277.486,0],[0,277.486],[-277.486,0],[0,-277.486]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14"}],"ip":0,"op":178,"st":-18,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Group 15","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":16.8,"s":[224.992,60,0],"e":[16.502,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":63.6,"s":[16.502,60,0],"e":[16.502,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[16.502,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.200390625}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-4,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":13.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":31,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":48.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":66,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":83.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":101,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":118.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":136,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":153.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":171,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":188.4,"s":[100,100,100],"e":[90,90,100]},{"t":206.0001953125}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-131.713],[131.713,0],[0,131.713],[-131.713,0]],"o":[[0,131.713],[-131.713,0],[0,-131.713],[131.713,0]],"v":[[238.488,0],[0,238.488],[-238.488,0],[0,-238.488]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15"}],"ip":0,"op":178,"st":-19.2,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Group 16","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":15.6,"s":[224.992,60,0],"e":[-22.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":62.4,"s":[-22.496,60,0],"e":[-22.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-22.496,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.199609375}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-5,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":12.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":30,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":47.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":65,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":82.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":100,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":117.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":135,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":152.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":170,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":187.4,"s":[100,100,100],"e":[90,90,100]},{"t":205.000390625}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-110.175],[110.175,0],[0,110.175],[-110.175,0]],"o":[[0,110.175],[-110.175,0],[0,-110.175],[110.175,0]],"v":[[199.49,0],[0,199.49],[-199.49,0],[0,-199.49]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16"}],"ip":0,"op":178,"st":-20.4,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Group 17","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":14.4,"s":[224.992,60,0],"e":[-65.994,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":61.2,"s":[-65.994,60,0],"e":[-65.994,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-65.994,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.1998046875}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-6,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":11.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":29,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":46.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":64,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":81.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":99,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":116.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":134,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":151.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":169,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":186.399,"s":[100,100,100],"e":[90,90,100]},{"t":203.999609375}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-86.152],[86.152,0],[0,86.152],[-86.152,0]],"o":[[0,86.152],[-86.152,0],[0,-86.152],[86.152,0]],"v":[[155.992,0],[0,155.992],[-155.992,0],[0,-155.992]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17"}],"ip":0,"op":178,"st":-21.6,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"Group 18","parent":0,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":13.2,"s":[224.992,60,0],"e":[-104.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":60,"s":[-104.992,60,0],"e":[-104.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-104.992,60,0],"e":[58.1,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-7,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":10.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":28,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":45.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":63,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":80.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":98,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":115.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":133,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":150.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":168,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":185.399,"s":[100,100,100],"e":[90,90,100]},{"t":202.9998046875}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-64.614],[64.614,0],[0,64.614],[-64.614,0]],"o":[[0,64.614],[-64.614,0],[0,-64.614],[64.614,0]],"v":[[116.994,0],[0,116.994],[-116.994,0],[0,-116.994]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.97,0.49,0.37,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18"}],"ip":0,"op":178,"st":-22.8,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":3,"nm":"NULL CONTROL","parent":20,"ks":{"o":{"k":0},"r":{"k":[{"i":{"x":[0.38],"y":[1]},"o":{"x":[0.189],"y":[0]},"n":["0p38_1_0p189_0"],"t":127.2,"s":[180],"e":[0]},{"t":158.4001953125}]},"p":{"k":[{"i":{"x":0,"y":1},"o":{"x":0.013,"y":0},"n":"0_1_0p013_0","t":24,"s":[662.1,540,0],"e":[736.1,540,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.2,"y":0.2},"o":{"x":0.1,"y":0.1},"n":"0p2_0p2_0p1_0p1","t":60,"s":[736.1,540,0],"e":[736.1,540,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0,"y":1},"o":{"x":0.05,"y":0},"n":"0_1_0p05_0","t":127.2,"s":[736.1,540,0],"e":[538.514,540,0],"to":[0,0,0],"ti":[0,0,0]},{"t":158.4001953125}]},"a":{"k":[60,60,0]},"s":{"k":[74,74,100]}},"ao":0,"ip":0,"op":178,"st":-22.8,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"Group 27","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.609,"y":0.609},"o":{"x":0.167,"y":0.167},"n":"0p609_0p609_0p167_0p167","t":22.8,"s":[224.992,60,0],"e":[224.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.051,"y":1},"o":{"x":0.167,"y":0},"n":"0p051_1_0p167_0","t":127.2,"s":[224.992,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.200390625}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-34,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-16.6,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":1,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":18.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":36,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":53.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":71,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":88.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":106,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":123.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":141,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":158.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":176,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":193.4,"s":[100,100,100],"e":[90,90,100]},{"t":211.0001953125}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-246.859],[246.859,0],[0,246.859],[-246.859,0]],"o":[[0,246.859],[-246.859,0],[0,-246.859],[246.859,0]],"v":[[446.978,0],[0,446.978],[-446.977,0],[0,-446.978]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10"}],"ip":0,"op":178,"st":-13.2,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"Group 26","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":21.6,"s":[224.991,60,0],"e":[181.494,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":68.4,"s":[181.494,60,0],"e":[181.494,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[181.494,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.199609375}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":0,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":17.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":35,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":52.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":70,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":87.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":105,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":122.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":140,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":157.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":175,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":192.4,"s":[100,100,100],"e":[90,90,100]},{"t":210.000390625}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-222.836],[222.836,0],[0,222.836],[-222.836,0]],"o":[[0,222.836],[-222.836,0],[0,-222.836],[222.836,0]],"v":[[403.48,0],[0,403.48],[-403.48,0],[0,-403.48]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11"}],"ip":0,"op":178,"st":-14.4,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":4,"nm":"Group 25","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":20.4,"s":[224.992,60,0],"e":[139.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":67.2,"s":[139.496,60,0],"e":[139.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[139.496,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.1998046875}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-1,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":16.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":34,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":51.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":69,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":86.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":104,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":121.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":139,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":156.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":174,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":191.399,"s":[100,100,100],"e":[90,90,100]},{"t":208.999609375}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-199.641],[199.641,0],[0,199.641],[-199.641,0]],"o":[[0,199.641],[-199.641,0],[0,-199.641],[199.641,0]],"v":[[361.482,0],[0,361.482],[-361.482,0],[0,-361.482]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12"}],"ip":0,"op":178,"st":-15.6,"bm":0,"sr":1},{"ddd":0,"ind":14,"ty":4,"nm":"Group 24","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":19.2,"s":[224.992,60,0],"e":[97.498,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":66,"s":[97.498,60,0],"e":[97.498,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[97.498,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-2,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":15.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":33,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":50.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":68,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":85.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":103,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":120.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":138,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":155.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":173,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":190.399,"s":[100,100,100],"e":[90,90,100]},{"t":207.9998046875}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-176.446],[176.446,0],[0,176.446],[-176.446,0]],"o":[[0,176.446],[-176.446,0],[0,-176.446],[176.446,0]],"v":[[319.484,0],[0,319.484],[-319.484,0],[0,-319.484]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13"}],"ip":0,"op":178,"st":-16.8,"bm":0,"sr":1},{"ddd":0,"ind":15,"ty":4,"nm":"Group 23","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":18,"s":[224.992,60,0],"e":[55.5,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":64.8,"s":[55.5,60,0],"e":[55.5,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[55.5,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2001953125}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":-3,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":14.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":32,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":49.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":67,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":84.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":102,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":119.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":137,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":154.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":172,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":189.399,"s":[100,100,100],"e":[90,90,100]},{"t":207}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-153.251],[153.251,0],[0,153.251],[-153.251,0]],"o":[[0,153.251],[-153.251,0],[0,-153.251],[153.251,0]],"v":[[277.486,0],[0,277.486],[-277.486,0],[0,-277.486]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14"}],"ip":0,"op":178,"st":-18,"bm":0,"sr":1},{"ddd":0,"ind":16,"ty":4,"nm":"Group 22","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":16.8,"s":[224.992,60,0],"e":[16.502,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":63.6,"s":[16.502,60,0],"e":[16.502,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[16.502,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.200390625}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-4,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":13.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":31,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":48.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":66,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":83.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":101,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":118.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":136,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":153.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":171,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":188.4,"s":[100,100,100],"e":[90,90,100]},{"t":206.0001953125}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-131.713],[131.713,0],[0,131.713],[-131.713,0]],"o":[[0,131.713],[-131.713,0],[0,-131.713],[131.713,0]],"v":[[238.488,0],[0,238.488],[-238.488,0],[0,-238.488]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15"}],"ip":0,"op":178,"st":-19.2,"bm":0,"sr":1},{"ddd":0,"ind":17,"ty":4,"nm":"Group 21","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":15.6,"s":[224.992,60,0],"e":[-22.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":62.4,"s":[-22.496,60,0],"e":[-22.496,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-22.496,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.199609375}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-5,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":12.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":30,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":47.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":65,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":82.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":100,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":117.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":135,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":152.4,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":170,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":187.4,"s":[100,100,100],"e":[90,90,100]},{"t":205.000390625}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-110.175],[110.175,0],[0,110.175],[-110.175,0]],"o":[[0,110.175],[-110.175,0],[0,-110.175],[110.175,0]],"v":[[199.49,0],[0,199.49],[-199.49,0],[0,-199.49]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16"}],"ip":0,"op":178,"st":-20.4,"bm":0,"sr":1},{"ddd":0,"ind":18,"ty":4,"nm":"Group 20","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":14.4,"s":[224.992,60,0],"e":[-65.994,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":61.2,"s":[-65.994,60,0],"e":[-65.994,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-65.994,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.1998046875}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-6,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":11.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":29,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":46.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":64,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":81.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":99,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":116.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":134,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":151.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":169,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":186.399,"s":[100,100,100],"e":[90,90,100]},{"t":203.999609375}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-86.152],[86.152,0],[0,86.152],[-86.152,0]],"o":[[0,86.152],[-86.152,0],[0,-86.152],[86.152,0]],"v":[[155.992,0],[0,155.992],[-155.992,0],[0,-155.992]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17"}],"ip":0,"op":178,"st":-21.6,"bm":0,"sr":1},{"ddd":0,"ind":19,"ty":4,"nm":"Group 19","parent":10,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[{"i":{"x":0.036,"y":1},"o":{"x":0.333,"y":0},"n":"0p036_1_0p333_0","t":13.2,"s":[224.992,60,0],"e":[-104.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":0.036},"o":{"x":0.167,"y":0.167},"n":"0p036_0p036_0p167_0p167","t":60,"s":[-104.992,60,0],"e":[-104.992,60,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.036,"y":1},"o":{"x":0.167,"y":0},"n":"0p036_1_0p167_0","t":127.2,"s":[-104.992,60,0],"e":[62,60,0],"to":[0,0,0],"ti":[0,0,0]},{"t":157.2}]},"a":{"k":[960,540,0]},"s":{"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":-7,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":10.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":28,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":45.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":63,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":80.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":98,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":115.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p2_1_0p167_0","0p2_1_0p167_0","0p2_0p2_0p167_0p167"],"t":133,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":150.399,"s":[100,100,100],"e":[90,90,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":168,"s":[90,90,100],"e":[100,100,100]},{"i":{"x":[0.2,0.2,0.2],"y":[1,1,0.2]},"o":{"x":[0.1,0.1,0.1],"y":[0,0,0.1]},"n":["0p2_1_0p1_0","0p2_1_0p1_0","0p2_0p2_0p1_0p1"],"t":185.399,"s":[100,100,100],"e":[90,90,100]},{"t":202.9998046875}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"k":{"i":[[0,-64.614],[64.614,0],[0,64.614],[-64.614,0]],"o":[[0,64.614],[-64.614,0],[0,-64.614],[64.614,0]],"v":[[116.994,0],[0,116.994],[-116.994,0],[0,-116.994]],"c":true}},"nm":"Path 1"},{"ty":"st","fillEnabled":true,"c":{"k":[0.24,0.74,0.36,1]},"o":{"k":100},"w":{"k":8},"lc":2,"lj":2,"nm":"Stroke 1"},{"ty":"tr","p":{"k":[960,540],"ix":2},"a":{"k":[0,0],"ix":1},"s":{"k":[100,100],"ix":3},"r":{"k":0,"ix":6},"o":{"k":100,"ix":7},"sk":{"k":0,"ix":4},"sa":{"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18"}],"ip":0,"op":178,"st":-22.8,"bm":0,"sr":1},{"ddd":0,"ind":20,"ty":1,"nm":"Dark Gray Solid 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[90,90,0]},"a":{"k":[540,540,0]},"s":{"k":[16.667,16.667,100]}},"ao":0,"sw":1080,"sh":1080,"sc":"#303030","ip":0,"op":178,"st":-22.8,"bm":0,"sr":1}],"v":"4.4.26","ddd":0,"ip":0,"op":176,"fr":30,"w":180,"h":180} --------------------------------------------------------------------------------