├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── art └── sample.gif ├── build.gradle ├── dependencies.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── library-date ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── io │ └── denison │ └── typedvalue │ └── date │ ├── DateValue.kt │ ├── LocalDateTimeValue.kt │ ├── LocalDateValue.kt │ └── TimeIntervalValue.kt ├── library ├── build.gradle └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── io │ │ └── denison │ │ └── typedvalue │ │ ├── KeyValueDelegate.kt │ │ ├── TypedValue.kt │ │ ├── common │ │ ├── BoolValue.kt │ │ ├── DoubleValue.kt │ │ ├── FloatValue.kt │ │ ├── IntValue.kt │ │ ├── LongValue.kt │ │ ├── ParcelableValue.kt │ │ ├── StringListValue.kt │ │ ├── StringSetValue.kt │ │ └── StringValue.kt │ │ └── delegate │ │ ├── BundleDelegate.kt │ │ ├── MapDelegate.kt │ │ └── PreferenceDelegate.kt │ └── test │ └── java │ └── io │ └── denison │ └── typedvalue │ ├── BundleDelegateTest.kt │ ├── MapDelegateTest.kt │ └── PreferenceDelegateTest.kt ├── sample ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── io │ │ └── denison │ │ └── typedvalue │ │ └── sample │ │ ├── MainActivity.kt │ │ ├── SampleApplication.kt │ │ ├── di │ │ ├── AppComponent.kt │ │ ├── AppModule.kt │ │ └── ViewScope.kt │ │ ├── model │ │ └── AnimationType.kt │ │ ├── mvp │ │ ├── MvpPresenter.kt │ │ ├── MvpView.kt │ │ ├── presenter │ │ │ └── BasePresenter.kt │ │ └── view │ │ │ └── MvpConstraintLayout.kt │ │ ├── preferences │ │ ├── AppPreferences.kt │ │ ├── AppPreferencesImpl.kt │ │ └── value │ │ │ └── AnimationTypeValue.kt │ │ └── ui │ │ ├── animation │ │ ├── AnimationComponent.kt │ │ ├── AnimationLayout.kt │ │ ├── AnimationPresenter.kt │ │ └── AnimationView.kt │ │ └── settings │ │ ├── SettingsComponent.kt │ │ ├── SettingsLayout.kt │ │ ├── SettingsPresenter.kt │ │ └── SettingsView.kt │ └── res │ ├── drawable-v21 │ └── setting_item_bkg.xml │ ├── drawable │ └── setting_item_bkg.xml │ ├── font │ ├── fonts.xml │ └── roboto_medium.ttf │ ├── layout │ └── ac_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── raw │ ├── confetti.json │ ├── favourite.json │ └── plane.json │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Android Studio 2 | .idea 3 | *.iml 4 | .externalNativeBuild 5 | .gradle/ 6 | build/ 7 | captures/ 8 | 9 | # Local configuration file (sdk path, etc) 10 | local.properties 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | sudo: false 3 | 4 | jdk: 5 | - oraclejdk8 6 | 7 | android: 8 | components: 9 | - tools 10 | - platform-tools 11 | - build-tools-28.0.2 12 | - android-28 13 | - extra-android-m2repository 14 | - extra-google-m2repository 15 | 16 | cache: 17 | directories: 18 | - $HOME/.m2 19 | - $HOME/.gradle 20 | 21 | before_script: 22 | - chmod +x gradlew 23 | 24 | script: 25 | - ./gradlew library:build library-date:build 26 | 27 | after_success: 28 | - ./gradlew jacocoTestReport && bash <(curl -s https://codecov.io/bash) 29 | 30 | env: 31 | global: 32 | - secure: cnxxpwWf6vcAq+NlTqKUv8lFG0u7leTnw/zyk3Ujxf/McGAKoUmxji14ClgncD1iFt8MRxXAs/E3wpBM6lH+cclTcC77eDKSvcvU4Tc8F8hty/u7fZGDcQQjYq/HKYM0qYAfCbkB3CEfoAqwB5WS0mT2Dh9x3vv9tDYuDsoZu6dWzy8kHc5V1bejgFmP75u5nMeRxgIXIUwqE6JtiueYrioNjAz5Rn79xZ6TwJaGD3PRt+nuuZdom+7OtZPOgkW4YtHaHmvBhnDI+6bu9R1hwqff/07nn9Q0wiKGeiGd0hnIejvGhZuIrLJ7+ZLMORdWssqfc1QMX4J2hW0xYDNYbuwFzpJIH2EhLrPSLp7BR+UVL4M8U0u1gmmHTTiYITqC3oLw9NMuj3yrJavKnli34fPSsvOHK1pt0pPy4tP4/9wZZgxoo2MTApmtRl7HcZ7oRzCW++ExzKIAP5MjwvSZ9tvMgS+pT6k9P4/+9ajGHWR8SSsxr6vNk+UtZ2r7m8dxi5yQInbP9VXuEtkGVfceO21C2tEAUpWtaFYpkSZcp3FXRrHNYFs677VZx+sZ5iGJ8qhJDfo2M/Ti3S2KeFffe/ORr95OAfyTeIbg1bjYoJjw5wK2bUN75j97tPGwl5NQU0SHKGBfh1rvPHBHABcXhNfznVF3onBxRB5IYS7AVE4= 33 | - secure: HfgUt9NsOqF9j7ayaFe/jwvFVvagQTAVc0EuqYFinlAmAd5NS7YRRZb8wwABnsyHc7KH+RA5AtFc1yIzwjeH5siC+LDXbmN8sAKjS2/pROxjdZZbdL3V3YnzD/ZF1J7ab5MeaAR1Le6rHVBs6uKOgb2MKIMiLIfYjnOb2+U7Np/ZNkRw+SggClD1ohTWvv/F3UdtrZp9yhkusMjpOiMVjL+DhQlLgFLMoI3oZDBrjXfMqAJ0EjglbBWkoiWIgTUeBziy9LVl5uPTrTg81vPTDREAiyV3gJHmlbH79aqy3ulxusu4RaEo/dVVlaUfCoqfmMDYfGZvQ5gSKgpDo18kbQd1f9Rk2os/B4sjqJu0ZiKvsDbIFFcPQlAfwikyqtyK4QCU/aq/L7Hwa2XKtt6tN0Yi30IHqtSUbt13zsF00injqzitxUap3n9UeW6K+QteGK9WlAHeBZA0RM5HvuC5Szyji2ZzX9Bp+Xn8j6+4tIR4codsaKnj2fSaKejtpjuf5pxy+ng9gSEOBacmWSdYjPq0Fl2UeY/Mcw3hPt5ds6z1bXL8oMMTb7/MIjsWEvWXi5dLyMrjfjOBkmWEMw9G2dHc9polTUhP9cKqMmzNoOMpjFoIGMnnXaix79iarlja0mto6u/7ga9ldl9O7qsikT0SfoMbp53OYHiJHdwswQ8= 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypedValue 2 | [![Build Status](https://travis-ci.org/YuriDenison/typedvalue.svg?branch=master)](https://travis-ci.org/YuriDenison/typedvalue) 3 | [![API](https://img.shields.io/badge/API-14%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=14) 4 | [![Download](https://api.bintray.com/packages/volkman/android/typedvalue/images/download.svg) ](https://bintray.com/volkman/android/typedvalue/_latestVersion) 5 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-TypedValue-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/6872) 6 | ![License](https://img.shields.io/badge/license-apache%202.0-blue.svg) 7 | 8 | TypedValue is a tiny library project to simplify access to SharedPreferences, Bundle or any other key-value storage with it's own [`KeyValueDelegate`][key_value_delegate] 9 | 10 | Common values are available out of the box: 11 | * [BoolValue][bool_value] 12 | * [StringValue][string_value] 13 | * [IntValue][int_value] 14 | * [LongValue][long_value] 15 | * [FloatValue][float_value] 16 | * [DoubleValue][double_value] 17 | * [ParcelableValue][parcelable_value] 18 | * [StringListValue][string_list_value] 19 | * [StringSetValue][string_set_value] 20 | 21 | Date module contains custom TypedValues for managing dates: 22 | * [DateValue][date_value] 23 | * [LocalDateValue][local_date_value] 24 | * [LocalDateTimeValue][local_date_time_value] 25 | 26 | For `java.time` entities [ThreeTen][threeten] library is used. 27 | 28 | 29 | ## Demo app 30 | ![image](https://github.com/YuriDenison/typedvalue/blob/master/art/sample.gif) 31 | 32 | The `sample` application demonstrates: 33 | * Convenient way to manage application preferences: [AppPreferences][app_preferences] and [AppPreferencesImpl][app_preferences_impl] 34 | 35 | Any calls (`get()`, `set()`, `asObservable()`, etc.) of each preference can be easily find via interface properties 36 | ``` kotlin 37 | interface AppPreferences { 38 | val animationTypeValue: AnimationTypeValue 39 | val scaleValue: FloatValue 40 | val messageShownValue: BoolValue 41 | } 42 | ``` 43 | ``` kotlin 44 | class AppPreferencesImpl(app: Application) : AppPreferences { 45 | private val delegate = PreferenceDelegate(PreferenceManager.getDefaultSharedPreferences(app)) 46 | 47 | override val animationTypeValue: AnimationTypeValue by lazy { AnimationTypeValue(delegate, KEY_ANIMATION_TYPE, AnimationType.CONFETTI) } 48 | override val scaleValue: FloatValue by lazy { FloatValue(delegate, KEY_SCALE, 0.8f) } 49 | override val messageShownValue: BoolValue by lazy { BoolValue(delegate, KEY_MESSAGE_SHOWN) } 50 | 51 | private companion object { 52 | const val KEY_ANIMATION_TYPE = ".key_animation_type" 53 | const val KEY_SCALE = ".key_scale" 54 | const val KEY_MESSAGE_SHOWN = ".key_message_shown" 55 | } 56 | } 57 | ``` 58 | 59 | 60 | * benefits of observable SharedPreferences with uni-directional data flow of ['SettingsPresenter'][settings_presenter] 61 | * custom [TypedValue][typed_value]: [AnimationTypeValue][animation_type_value] 62 | 63 | ## Installation 64 | Add the following dependency to your `build.gradle` file: 65 | 66 | ``` 67 | dependencies { 68 | implementation 'io.denison:typedvalue:${LATEST_VERSION}' 69 | implementation 'io.denison:typedvalue-date:${LATEST_VERSION}' 70 | } 71 | ``` 72 | 73 | ## License 74 | Please see [LICENSE](/LICENSE) 75 | 76 | 77 | [key_value_delegate]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/KeyValueDelegate.kt 78 | [typed_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/TypedValue.kt 79 | [animation_type_value]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/value/AnimationTypeValue.kt 80 | [settings_presenter]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsPresenter.kt 81 | [app_preferences]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferences.kt 82 | [app_preferences_impl]: https://github.com/YuriDenison/typedvalue/blob/master/sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferencesImpl.kt 83 | [bool_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/BoolValue.kt 84 | [double_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/DoubleValue.kt 85 | [float_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/FloatValue.kt 86 | [int_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/IntValue.kt 87 | [long_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/LongValue.kt 88 | [parcelable_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/ParcelableValue.kt 89 | [string_list_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringListValue.kt 90 | [string_set_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringSetValue.kt 91 | [string_value]: https://github.com/YuriDenison/typedvalue/blob/master/library/src/main/java/io/denison/typedvalue/common/StringValue.kt 92 | [date_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/DateValue.kt 93 | [local_date_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/LocalDateValue.kt 94 | [local_date_time_value]: https://github.com/YuriDenison/typedvalue/blob/master/library-date/src/main/java/io/denison/typedvalue/date/LocalDateTimeValue.kt 95 | [threeten]: https://github.com/JakeWharton/ThreeTenABP 96 | -------------------------------------------------------------------------------- /art/sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/art/sample.gif -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | apply from: 'dependencies.gradle' 3 | 4 | repositories { 5 | mavenLocal() 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath gradlePlugins.android 11 | classpath gradlePlugins.kotlin 12 | classpath gradlePlugins.bintray 13 | classpath gradlePlugins.versions 14 | classpath gradlePlugins.yacoco 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | mavenLocal() 21 | google() 22 | jcenter() 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | 30 | apply from: 'dependencies.gradle' 31 | apply plugin: 'com.github.ben-manes.versions' 32 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext.bintrayConstants = [ 2 | repoName : 'android', 3 | userOrg : 'volkman', 4 | libraryGroup : 'io.denison', 5 | libraryDesc : 'Typed value abstraction to deal with SharedPreferences, Bundle, etc.', 6 | github : 'https://github.com/YuriDenison/typedvalue.git', 7 | 8 | libraryVersion: '0.9.4' 9 | ] 10 | 11 | ext.versions = [ 12 | compileSdk : 28, 13 | buildTools : '28.0.3', 14 | 15 | androidGradlePlugin : '3.2.1', 16 | versionsGradlePlugin: '0.20.0', 17 | bintrayGradlePlugin : '1.8.4', 18 | yacocoGradlePlugin : '0.1.3', 19 | 20 | kotlin : '1.3.11', 21 | 22 | androidX : '1.0.1', 23 | appCompat : '1.0.2', 24 | constraintLayout : '2.0.0-alpha2', 25 | dagger : '2.19', 26 | gson : '2.8.2', 27 | lottie : '2.8.0', 28 | threeten : '1.1.1', 29 | 30 | rxAndroid2 : '2.1.0', 31 | rxJava2 : '2.2.4', 32 | rxKotlin : '2.3.0', 33 | rxRelay : '2.1.0', 34 | timber : '4.7.1', 35 | snackbar : '2.11.0', 36 | 37 | junit : '4.12', 38 | robolectric : '4.0.2', 39 | 40 | typedvalue : '0.9.4' 41 | ] 42 | 43 | ext.gradlePlugins = [ 44 | android : "com.android.tools.build:gradle:$versions.androidGradlePlugin", 45 | kotlin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin", 46 | versions: "com.github.ben-manes:gradle-versions-plugin:$versions.versionsGradlePlugin", 47 | bintray : "com.jfrog.bintray.gradle:gradle-bintray-plugin:$versions.bintrayGradlePlugin", 48 | yacoco : "com.dicedmelon.gradle:jacoco-android:$versions.yacocoGradlePlugin" 49 | ] 50 | 51 | ext.libraries = [ 52 | kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlin", 53 | 54 | androidAnnotations: "androidx.annotation:annotation:$versions.androidX", 55 | androidAppCompat : "androidx.appcompat:appcompat:$versions.appCompat", 56 | androidDesign : "com.google.android.material:material:$versions.androidX", 57 | constraintLayout : "androidx.constraintlayout:constraintlayout:$versions.constraintLayout", 58 | 59 | dagger : "com.google.dagger:dagger:$versions.dagger", 60 | daggerCompiler : "com.google.dagger:dagger-compiler:$versions.dagger", 61 | 62 | gson : "com.google.code.gson:gson:$versions.gson", 63 | lottie : "com.airbnb.android:lottie:$versions.lottie", 64 | timber : "com.jakewharton.timber:timber:$versions.timber", 65 | snackbar : "com.nispok:snackbar:$versions.snackbar", 66 | threeten : "com.jakewharton.threetenabp:threetenabp:$versions.threeten", 67 | 68 | rxAndroid2 : "io.reactivex.rxjava2:rxandroid:$versions.rxAndroid2", 69 | rxJava2 : "io.reactivex.rxjava2:rxjava:$versions.rxJava2", 70 | rxKotlin : "io.reactivex.rxjava2:rxkotlin:$versions.rxKotlin", 71 | rxRelay : "com.jakewharton.rxrelay2:rxrelay:$versions.rxRelay", 72 | 73 | junit : "junit:junit:$versions.junit", 74 | kotlinTestJunit : "org.jetbrains.kotlin:kotlin-test-junit:$versions.kotlin", 75 | robolectric : "org.robolectric:robolectric:$versions.robolectric", 76 | 77 | typedvalue : "io.denison:typedvalue:$versions.typedvalue" 78 | ] 79 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX=true 2 | android.enableJetifier=true 3 | android.enableR8=true 4 | android.enableR8.fullMode=true 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /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 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 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 Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /library-date/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'jacoco-android' 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'maven-publish' 5 | apply plugin: 'com.jfrog.bintray' 6 | 7 | version = bintrayConstants.libraryVersion 8 | group = bintrayConstants.libraryGroup 9 | 10 | android { 11 | compileSdkVersion versions.compileSdk 12 | buildToolsVersion versions.buildTools 13 | 14 | defaultConfig { 15 | minSdkVersion 14 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation libraries.typedvalue 21 | implementation libraries.threeten 22 | 23 | testImplementation libraries.junit 24 | testImplementation libraries.kotlinTestJunit 25 | testImplementation libraries.robolectric 26 | } 27 | 28 | publishing { 29 | publications { 30 | Production(MavenPublication) { 31 | artifact("$buildDir/outputs/aar/library-date-release.aar") 32 | artifact sourcesJar 33 | 34 | groupId bintrayConstants.libraryGroup 35 | version bintrayConstants.libraryVersion 36 | artifactId 'typedvalue-date' 37 | 38 | pom.withXml { 39 | def dependenciesNode = asNode().appendNode('dependencies') 40 | 41 | configurations.implementation.allDependencies.each { 42 | if (it.name != 'unspecified') { 43 | def dependencyNode = dependenciesNode.appendNode('dependency') 44 | dependencyNode.appendNode('groupId', it.group) 45 | dependencyNode.appendNode('artifactId', it.name) 46 | dependencyNode.appendNode('version', it.version) 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | bintray { 55 | user = project.hasProperty("bintrayUser") ? project.getProperty("bintrayUser") : System.getenv('BINTRAY_USER') 56 | key = project.hasProperty("bintrayKey") ? project.getProperty("bintrayKey") : System.getenv('BINTRAY_KEY') 57 | publications = ['Production'] 58 | configurations = ['archives'] 59 | override = true 60 | 61 | pkg { 62 | repo = bintrayConstants.repoName 63 | name = 'typedvalue-date' 64 | userOrg = bintrayConstants.userOrg 65 | licenses = ['Apache-2.0'] 66 | vcsUrl = bintrayConstants.github 67 | dryRun = false 68 | publish = true 69 | 70 | version { 71 | name = bintrayConstants.libraryVersion 72 | desc = bintrayConstants.libraryDesc 73 | } 74 | } 75 | } 76 | 77 | task sourcesJar(type: Jar) { 78 | classifier = 'sources' 79 | from android.sourceSets.main.java.srcDirs 80 | } 81 | 82 | artifacts { 83 | archives sourcesJar 84 | } 85 | -------------------------------------------------------------------------------- /library-date/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /library-date/src/main/java/io/denison/typedvalue/date/DateValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.date 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | import java.util.Date 6 | 7 | class DateValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Date = Date()) : TypedValue(delegate, key, defaultValue) { 8 | override fun get(): Date = Date(delegate.getLong(key, 0)) 9 | override fun set(value: Date) = delegate.putLong(key, value.time) 10 | } -------------------------------------------------------------------------------- /library-date/src/main/java/io/denison/typedvalue/date/LocalDateTimeValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.date 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | import org.threeten.bp.Clock 6 | import org.threeten.bp.Instant 7 | import org.threeten.bp.LocalDateTime 8 | import org.threeten.bp.ZoneOffset 9 | 10 | class LocalDateTimeValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: LocalDateTime = LocalDateTime.now()) : TypedValue(delegate, key, defaultValue) { 11 | override fun get(): LocalDateTime = Instant.ofEpochMilli(delegate.getLong(key, 0)).atZone(Clock.systemUTC().zone).toLocalDateTime() 12 | override fun set(value: LocalDateTime) = delegate.putLong(key, value.toInstant(ZoneOffset.UTC).toEpochMilli()) 13 | } -------------------------------------------------------------------------------- /library-date/src/main/java/io/denison/typedvalue/date/LocalDateValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.date 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | import org.threeten.bp.Clock 6 | import org.threeten.bp.Instant 7 | import org.threeten.bp.LocalDate 8 | 9 | class LocalDateValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: LocalDate = LocalDate.now()) : TypedValue(delegate, key, defaultValue) { 10 | override fun get(): LocalDate = Instant.ofEpochMilli(delegate.getLong(key, 0)).atZone(Clock.systemUTC().zone).toLocalDate() 11 | override fun set(value: LocalDate) = delegate.putLong(key, value.atStartOfDay(Clock.systemUTC().zone).toInstant().toEpochMilli()) 12 | } -------------------------------------------------------------------------------- /library-date/src/main/java/io/denison/typedvalue/date/TimeIntervalValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.date 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.common.LongValue 5 | 6 | class TimeIntervalValue(delegate: KeyValueDelegate, key: String) : LongValue(delegate, key) { 7 | private var duration = 0L 8 | 9 | fun trackStart() = set(System.currentTimeMillis()) 10 | fun trackEnd() { 11 | duration += System.currentTimeMillis() - get() 12 | } 13 | 14 | fun getMillis(): Long = duration 15 | fun getSeconds(): Long = duration / 1000 16 | } -------------------------------------------------------------------------------- /library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'jacoco-android' 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'maven-publish' 5 | apply plugin: 'com.jfrog.bintray' 6 | 7 | version = bintrayConstants.libraryVersion 8 | group = bintrayConstants.libraryGroup 9 | 10 | android { 11 | compileSdkVersion versions.compileSdk 12 | buildToolsVersion versions.buildTools 13 | 14 | defaultConfig { 15 | minSdkVersion 14 16 | } 17 | } 18 | 19 | dependencies { 20 | implementation libraries.kotlinStdLib 21 | implementation libraries.rxJava2 22 | 23 | testImplementation libraries.junit 24 | testImplementation libraries.kotlinTestJunit 25 | testImplementation libraries.robolectric 26 | } 27 | 28 | publishing { 29 | publications { 30 | Production(MavenPublication) { 31 | artifact("$buildDir/outputs/aar/library-release.aar") 32 | artifact sourcesJar 33 | 34 | groupId bintrayConstants.libraryGroup 35 | version bintrayConstants.libraryVersion 36 | artifactId 'typedvalue' 37 | 38 | pom.withXml { 39 | def dependenciesNode = asNode().appendNode('dependencies') 40 | 41 | configurations.implementation.allDependencies.each { 42 | if (it.name != 'unspecified') { 43 | def dependencyNode = dependenciesNode.appendNode('dependency') 44 | dependencyNode.appendNode('groupId', it.group) 45 | dependencyNode.appendNode('artifactId', it.name) 46 | dependencyNode.appendNode('version', it.version) 47 | } 48 | } 49 | } 50 | } 51 | } 52 | } 53 | 54 | bintray { 55 | user = project.hasProperty("bintrayUser") ? project.getProperty("bintrayUser") : System.getenv('BINTRAY_USER') 56 | key = project.hasProperty("bintrayKey") ? project.getProperty("bintrayKey") : System.getenv('BINTRAY_KEY') 57 | publications = ['Production'] 58 | configurations = ['archives'] 59 | override = true 60 | 61 | pkg { 62 | repo = bintrayConstants.repoName 63 | name = 'typedvalue' 64 | userOrg = bintrayConstants.userOrg 65 | licenses = ['Apache-2.0'] 66 | vcsUrl = bintrayConstants.github 67 | dryRun = false 68 | publish = true 69 | 70 | version { 71 | name = bintrayConstants.libraryVersion 72 | desc = bintrayConstants.libraryDesc 73 | } 74 | } 75 | } 76 | 77 | task sourcesJar(type: Jar) { 78 | classifier = 'sources' 79 | from android.sourceSets.main.java.srcDirs 80 | } 81 | 82 | artifacts { 83 | archives sourcesJar 84 | } 85 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/KeyValueDelegate.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue 2 | 3 | import android.os.Parcelable 4 | import io.reactivex.Observable 5 | 6 | interface KeyValueDelegate { 7 | 8 | fun getInt(key: String, defaultValue: Int): Int 9 | fun putInt(key: String, value: Int) 10 | 11 | fun getBoolean(key: String, defaultValue: Boolean): Boolean 12 | fun putBoolean(key: String, value: Boolean) 13 | 14 | fun getLong(key: String, defaultValue: Long): Long 15 | fun putLong(key: String, value: Long) 16 | 17 | fun getString(key: String, defaultValue: String): String 18 | fun putString(key: String, value: String) 19 | 20 | fun getDouble(key: String, defaultValue: Double): Double 21 | fun putDouble(key: String, value: Double) 22 | 23 | fun getFloat(key: String, defaultValue: Float): Float 24 | fun putFloat(key: String, value: Float) 25 | 26 | fun getStringSet(key: String, defaultValue: Set): Set 27 | fun putStringSet(key: String, value: Set) 28 | 29 | fun getStringList(key: String, defaultValue: List): List 30 | fun putStringList(key: String, value: List) 31 | 32 | fun getParcelable(key: String, defaultValue: T): T 33 | fun putParcelable(key: String, value: T) 34 | 35 | operator fun contains(key: String): Boolean 36 | 37 | fun remove(key: String) 38 | 39 | fun clear() 40 | 41 | fun keyChanges(): Observable 42 | } 43 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/TypedValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue 2 | 3 | import io.reactivex.Observable 4 | import io.reactivex.functions.Consumer 5 | 6 | abstract class TypedValue protected constructor(protected val delegate: KeyValueDelegate, val key: String, protected val defaultValue: T) { 7 | 8 | abstract fun get(): T 9 | abstract fun set(value: T) 10 | 11 | fun remove() = delegate.remove(key) 12 | 13 | open fun isSet(): Boolean = delegate.contains(key) 14 | 15 | fun asObservable(): Observable = delegate.keyChanges() 16 | .filter { k -> k == key } 17 | .startWith("") 18 | .map { get() } 19 | 20 | fun asConsumer(): Consumer = Consumer { set(it) } 21 | } 22 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/BoolValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | class BoolValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Boolean = EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getBoolean(key, defaultValue) 10 | override fun set(value: Boolean) = delegate.putBoolean(key, value) 11 | 12 | fun toggle() = set(!get()) 13 | 14 | companion object { 15 | const val EMPTY = false 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/DoubleValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | class DoubleValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Double = DoubleValue.EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getDouble(key, defaultValue) 10 | override fun set(value: Double) = delegate.putDouble(key, value) 11 | 12 | 13 | companion object { 14 | const val EMPTY = 0.0 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/FloatValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | class FloatValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Float = FloatValue.EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getFloat(key, defaultValue) 10 | override fun set(value: Float) = delegate.putFloat(key, value) 11 | 12 | companion object { 13 | const val EMPTY = 0.0f 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/IntValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | open class IntValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Int = IntValue.EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getInt(key, defaultValue) 10 | override fun set(value: Int) = delegate.putInt(key, value) 11 | 12 | fun increment() = set(get() + 1) 13 | fun decrement() = set(get() - 1) 14 | 15 | companion object { 16 | const val EMPTY = 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/LongValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | open class LongValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Long = LongValue.EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getLong(key, defaultValue) 10 | override fun set(value: Long) = delegate.putLong(key, value) 11 | 12 | companion object { 13 | const val EMPTY = 0L 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/ParcelableValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import android.os.Parcelable 4 | import io.denison.typedvalue.KeyValueDelegate 5 | import io.denison.typedvalue.TypedValue 6 | 7 | class ParcelableValue(delegate: KeyValueDelegate, key: String, defaultValue: T) : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getParcelable(key, defaultValue) 10 | override fun set(value: T) = delegate.putParcelable(key, value) 11 | } 12 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/StringListValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | class StringListValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: List = emptyList()) : TypedValue>(delegate, key, defaultValue) { 7 | 8 | override fun get() = delegate.getStringList(key, defaultValue) 9 | override fun set(value: List) = delegate.putStringList(key, value) 10 | } 11 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/StringSetValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | class StringSetValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: Set = emptySet()) : TypedValue>(delegate, key, defaultValue) { 7 | 8 | override fun get() = delegate.getStringSet(key, defaultValue) 9 | override fun set(value: Set) = delegate.putStringSet(key, value) 10 | } 11 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/common/StringValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.common 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | 6 | open class StringValue @JvmOverloads constructor(delegate: KeyValueDelegate, key: String, defaultValue: String = StringValue.EMPTY) 7 | : TypedValue(delegate, key, defaultValue) { 8 | 9 | override fun get() = delegate.getString(key, defaultValue) 10 | override fun set(value: String) = delegate.putString(key, value) 11 | 12 | override fun isSet() = delegate.contains(key) && EMPTY != get() 13 | 14 | companion object { 15 | const val EMPTY = "" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/delegate/BundleDelegate.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.delegate 2 | 3 | import android.os.Bundle 4 | import android.os.Parcelable 5 | import io.denison.typedvalue.KeyValueDelegate 6 | import io.reactivex.Observable 7 | import java.util.ArrayList 8 | 9 | class BundleDelegate(private val bundle: Bundle = Bundle()) : KeyValueDelegate { 10 | override fun getInt(key: String, defaultValue: Int) = bundle.getInt(key, defaultValue) 11 | override fun putInt(key: String, value: Int) = bundle.putInt(key, value) 12 | 13 | override fun getBoolean(key: String, defaultValue: Boolean) = bundle.getBoolean(key, defaultValue) 14 | override fun putBoolean(key: String, value: Boolean) = bundle.putBoolean(key, value) 15 | 16 | override fun getLong(key: String, defaultValue: Long) = bundle.getLong(key, defaultValue) 17 | override fun putLong(key: String, value: Long) = bundle.putLong(key, value) 18 | 19 | override fun getString(key: String, defaultValue: String): String = bundle.getString(key, defaultValue) 20 | override fun putString(key: String, value: String) = bundle.putString(key, value) 21 | 22 | override fun getDouble(key: String, defaultValue: Double) = bundle.getDouble(key, defaultValue) 23 | override fun putDouble(key: String, value: Double) = bundle.putDouble(key, value) 24 | 25 | override fun getFloat(key: String, defaultValue: Float) = bundle.getFloat(key, defaultValue) 26 | override fun putFloat(key: String, value: Float) = bundle.putFloat(key, value) 27 | 28 | override fun getStringSet(key: String, defaultValue: Set): Set = throw IllegalArgumentException("Unsupported type 'Set'") 29 | override fun putStringSet(key: String, value: Set) = throw IllegalArgumentException("Unsupported type 'Set'") 30 | 31 | override fun getStringList(key: String, defaultValue: List): List = bundle.getStringArrayList(key) ?: defaultValue 32 | override fun putStringList(key: String, value: List) = bundle.putStringArrayList(key, ArrayList(value)) 33 | 34 | override fun getParcelable(key: String, defaultValue: T): T = bundle.getParcelable(key) ?: defaultValue 35 | override fun putParcelable(key: String, value: T) = bundle.putParcelable(key, value) 36 | 37 | override fun remove(key: String) = bundle.remove(key) 38 | 39 | override fun clear() = bundle.clear() 40 | 41 | override fun keyChanges(): Observable = Observable.empty() 42 | 43 | override operator fun contains(key: String) = bundle.containsKey(key) 44 | } 45 | -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/delegate/MapDelegate.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.delegate 2 | 3 | import android.os.Parcelable 4 | import io.denison.typedvalue.KeyValueDelegate 5 | import io.reactivex.Observable 6 | import java.util.concurrent.ConcurrentHashMap 7 | 8 | class MapDelegate(private val map: MutableMap = ConcurrentHashMap()) : KeyValueDelegate { 9 | override fun getInt(key: String, defaultValue: Int): Int = map[key] as Int? ?: defaultValue 10 | override fun putInt(key: String, value: Int) { 11 | map[key] = value 12 | } 13 | 14 | override fun getBoolean(key: String, defaultValue: Boolean) = map[key] as Boolean? ?: defaultValue 15 | override fun putBoolean(key: String, value: Boolean) { 16 | map[key] = value 17 | } 18 | 19 | override fun getLong(key: String, defaultValue: Long) = map[key] as Long? ?: defaultValue 20 | override fun putLong(key: String, value: Long) { 21 | map[key] = value 22 | } 23 | 24 | override fun getString(key: String, defaultValue: String) = map[key] as String? ?: defaultValue 25 | override fun putString(key: String, value: String) { 26 | map[key] = value 27 | } 28 | 29 | override fun getDouble(key: String, defaultValue: Double) = map[key] as Double? ?: defaultValue 30 | override fun putDouble(key: String, value: Double) { 31 | map[key] = value 32 | } 33 | 34 | override fun getFloat(key: String, defaultValue: Float) = map[key] as Float? ?: defaultValue 35 | override fun putFloat(key: String, value: Float) { 36 | map[key] = value 37 | } 38 | 39 | @Suppress("UNCHECKED_CAST") 40 | override fun getStringSet(key: String, defaultValue: Set): Set = map[key] as Set? ?: defaultValue 41 | 42 | override fun putStringSet(key: String, value: Set) { 43 | map[key] = value 44 | } 45 | 46 | @Suppress("UNCHECKED_CAST") 47 | override fun getStringList(key: String, defaultValue: List) = map[key] as List? ?: defaultValue 48 | 49 | override fun putStringList(key: String, value: List) { 50 | map[key] = value 51 | } 52 | 53 | @Suppress("UNCHECKED_CAST") 54 | override fun getParcelable(key: String, defaultValue: T): T = map[key] as T? ?: defaultValue 55 | 56 | override fun putParcelable(key: String, value: T) { 57 | map[key] = value 58 | } 59 | 60 | override fun contains(key: String): Boolean = map.contains(key) 61 | 62 | override fun remove(key: String) { 63 | map.remove(key) 64 | } 65 | 66 | override fun clear() = map.clear() 67 | 68 | override fun keyChanges(): Observable = Observable.empty() 69 | } -------------------------------------------------------------------------------- /library/src/main/java/io/denison/typedvalue/delegate/PreferenceDelegate.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.delegate 2 | 3 | import android.content.SharedPreferences 4 | import android.os.Parcelable 5 | import io.denison.typedvalue.KeyValueDelegate 6 | import io.reactivex.Observable 7 | import io.reactivex.ObservableOnSubscribe 8 | import java.lang.Double.doubleToLongBits 9 | import java.lang.Double.longBitsToDouble 10 | 11 | class PreferenceDelegate(private val prefs: SharedPreferences) : KeyValueDelegate { 12 | private val keyChangesObservable: Observable 13 | 14 | init { 15 | keyChangesObservable = io.reactivex.Observable.create(ObservableOnSubscribe { emitter -> 16 | val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> emitter.onNext(key) } 17 | emitter.setCancellable { prefs.unregisterOnSharedPreferenceChangeListener(listener) } 18 | prefs.registerOnSharedPreferenceChangeListener(listener) 19 | }).share() 20 | } 21 | 22 | override fun getInt(key: String, defaultValue: Int) = prefs.getInt(key, defaultValue) 23 | override fun putInt(key: String, value: Int) = prefs.edit().putInt(key, value).apply() 24 | 25 | override fun getString(key: String, defaultValue: String): String = prefs.getString(key, defaultValue) ?: defaultValue 26 | override fun putString(key: String, value: String) = prefs.edit().putString(key, value).apply() 27 | 28 | override fun getBoolean(key: String, defaultValue: Boolean) = prefs.getBoolean(key, defaultValue) 29 | override fun putBoolean(key: String, value: Boolean) = prefs.edit().putBoolean(key, value).apply() 30 | 31 | override fun getLong(key: String, defaultValue: Long) = prefs.getLong(key, defaultValue) 32 | override fun putLong(key: String, value: Long) = prefs.edit().putLong(key, value).apply() 33 | 34 | override fun getDouble(key: String, defaultValue: Double) = longBitsToDouble(prefs.getLong(key, doubleToLongBits(defaultValue))) 35 | override fun putDouble(key: String, value: Double) = prefs.edit().putLong(key, doubleToLongBits(value)).apply() 36 | 37 | override fun getFloat(key: String, defaultValue: Float) = prefs.getFloat(key, defaultValue) 38 | override fun putFloat(key: String, value: Float) = prefs.edit().putFloat(key, value).apply() 39 | 40 | override fun getStringSet(key: String, defaultValue: Set): Set = prefs.getStringSet(key, defaultValue) ?: defaultValue 41 | override fun putStringSet(key: String, value: Set) = prefs.edit().putStringSet(key, value).apply() 42 | 43 | override fun getStringList(key: String, defaultValue: List) = throw IllegalArgumentException("Unsupported type 'List'") 44 | override fun putStringList(key: String, value: List) = throw IllegalArgumentException("Unsupported type 'List'") 45 | 46 | override fun getParcelable(key: String, defaultValue: T): T = throw IllegalArgumentException("Unsupported type 'Parcelable'") 47 | override fun putParcelable(key: String, value: T) = throw IllegalArgumentException("Unsupported type 'Parcelable'") 48 | 49 | override operator fun contains(key: String) = prefs.contains(key) 50 | 51 | override fun remove(key: String) = prefs.edit().remove(key).apply() 52 | 53 | override fun clear() = prefs.edit().clear().apply() 54 | 55 | override fun keyChanges(): Observable = keyChangesObservable 56 | } 57 | -------------------------------------------------------------------------------- /library/src/test/java/io/denison/typedvalue/BundleDelegateTest.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue 2 | 3 | import android.os.Bundle 4 | import io.denison.typedvalue.delegate.BundleDelegate 5 | import org.junit.Before 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | import org.robolectric.RobolectricTestRunner 9 | import kotlin.test.assertEquals 10 | import kotlin.test.assertFails 11 | import kotlin.test.assertFalse 12 | import kotlin.test.assertTrue 13 | 14 | @RunWith(RobolectricTestRunner::class) 15 | class BundleDelegateTest { 16 | private lateinit var bundle: Bundle 17 | private lateinit var delegate: BundleDelegate 18 | 19 | @Before 20 | fun setUp() { 21 | bundle = Bundle().apply { 22 | putInt(KEY_INT_DEFAULT, 1) 23 | putBoolean(KEY_BOOLEAN_DEFAULT, true) 24 | putLong(KEY_LONG_DEFAULT, 1) 25 | putString(KEY_STRING_DEFAULT, "default") 26 | putDouble(KEY_DOUBLE_DEFAULT, 1.0) 27 | putFloat(KEY_FLOAT_DEFAULT, 1f) 28 | putStringArrayList(KEY_STRING_LIST_DEFAULT, arrayListOf("default")) 29 | putParcelable(KEY_PARCELABLE_DEFAULT, PARCELABLE_BUNDLE) 30 | } 31 | delegate = BundleDelegate(bundle) 32 | } 33 | 34 | @Test 35 | fun testGetInt() { 36 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2)) 37 | assertEquals(2, delegate.getInt(KEY_INT, 2)) 38 | } 39 | 40 | @Test 41 | fun testPutInt() { 42 | delegate.putInt(KEY_INT, 1) 43 | assertEquals(1, bundle.getInt(KEY_INT)) 44 | } 45 | 46 | @Test 47 | fun testGetBoolean() { 48 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) } 49 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) } 50 | } 51 | 52 | @Test 53 | fun testPutBoolean() { 54 | delegate.putBoolean(KEY_BOOLEAN, true) 55 | assertEquals(true, bundle.getBoolean(KEY_BOOLEAN)) 56 | } 57 | 58 | @Test 59 | fun testGetLong() { 60 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2)) 61 | assertEquals(2, delegate.getLong(KEY_LONG, 2)) 62 | } 63 | 64 | @Test 65 | fun testPutLong() { 66 | delegate.putLong(KEY_LONG, 1) 67 | assertEquals(1, bundle.getLong(KEY_LONG)) 68 | } 69 | 70 | @Test 71 | fun testGetString() { 72 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val")) 73 | assertEquals("val", delegate.getString(KEY_STRING, "val")) 74 | } 75 | 76 | @Test 77 | fun testPutString() { 78 | delegate.putString(KEY_STRING, "val") 79 | assertEquals("val", bundle.getString(KEY_STRING)) 80 | } 81 | 82 | @Test 83 | fun testGetDouble() { 84 | assertEquals(1.0, delegate.getDouble(KEY_DOUBLE_DEFAULT, 2.0)) 85 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0)) 86 | } 87 | 88 | @Test 89 | fun testPutDouble() { 90 | delegate.putDouble(KEY_DOUBLE, 2.0) 91 | assertEquals(2.0, bundle.getDouble(KEY_DOUBLE)) 92 | } 93 | 94 | @Test 95 | fun testGetFloat() { 96 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f)) 97 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f)) 98 | } 99 | 100 | @Test 101 | fun testPutFloat() { 102 | delegate.putFloat(KEY_FLOAT, 2f) 103 | assertEquals(2f, bundle.getFloat(KEY_FLOAT)) 104 | } 105 | 106 | @Test 107 | fun testGetStringSet() { 108 | assertFails { delegate.getStringSet(KEY_STRING_SET, emptySet()) } 109 | } 110 | 111 | @Test 112 | fun testPutStringSet() { 113 | assertFails { delegate.putStringSet(KEY_STRING_SET, setOf()) } 114 | } 115 | 116 | @Test 117 | fun testGetStringList() { 118 | assertEquals(arrayListOf("default"), delegate.getStringList(KEY_STRING_LIST_DEFAULT, emptyList())) 119 | assertEquals(emptyList(), delegate.getStringList(KEY_STRING_LIST, emptyList())) 120 | } 121 | 122 | @Test 123 | fun testPutStringList() { 124 | delegate.putStringList(KEY_STRING_LIST, arrayListOf("val")) 125 | assertEquals(arrayListOf("val"), bundle.getStringArrayList(KEY_STRING_LIST)) 126 | } 127 | 128 | @Test 129 | fun testGetParcelable() { 130 | val bundle = Bundle() 131 | assertEquals(PARCELABLE_BUNDLE, delegate.getParcelable(KEY_PARCELABLE_DEFAULT, Bundle())) 132 | assertEquals(bundle, delegate.getParcelable(KEY_PARCELABLE, bundle)) 133 | } 134 | 135 | @Test 136 | fun testPutParcelable() { 137 | delegate.putParcelable(KEY_PARCELABLE, PARCELABLE_BUNDLE) 138 | assertEquals(PARCELABLE_BUNDLE, bundle.getParcelable(KEY_PARCELABLE)!!) 139 | } 140 | 141 | @Test 142 | fun testContains() { 143 | assertTrue { KEY_INT_DEFAULT in delegate } 144 | assertTrue { KEY_INT !in delegate } 145 | } 146 | 147 | @Test 148 | fun testRemove() { 149 | delegate.remove(KEY_INT_DEFAULT) 150 | assertTrue { KEY_INT_DEFAULT !in delegate } 151 | assertFalse { bundle.containsKey(KEY_INT_DEFAULT) } 152 | } 153 | 154 | @Test 155 | fun testClear() { 156 | delegate.clear() 157 | assertTrue { KEY_INT_DEFAULT !in delegate } 158 | assertTrue { bundle.isEmpty } 159 | } 160 | 161 | 162 | private companion object { 163 | const val KEY_INT = ".KEY_INT" 164 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT" 165 | const val KEY_BOOLEAN = "KEY_BOOLEAN" 166 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT" 167 | const val KEY_LONG = "KEY_LONG" 168 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT" 169 | const val KEY_STRING = "KEY_STRING" 170 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT" 171 | const val KEY_DOUBLE = "KEY_DOUBLE" 172 | const val KEY_DOUBLE_DEFAULT = "KEY_DOUBLE_DEFAULT" 173 | const val KEY_FLOAT = "KEY_FLOAT" 174 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT" 175 | const val KEY_STRING_SET = "KEY_STRING_SET" 176 | const val KEY_STRING_LIST = "KEY_STRING_LIST" 177 | const val KEY_STRING_LIST_DEFAULT = "KEY_STRING_LIST_DEFAULT" 178 | const val KEY_PARCELABLE = "KEY_PARCELABLE" 179 | const val KEY_PARCELABLE_DEFAULT = "KEY_PARCELABLE_DEFAULT" 180 | 181 | val PARCELABLE_BUNDLE = Bundle().apply { putInt(KEY_INT, 1) } 182 | } 183 | } -------------------------------------------------------------------------------- /library/src/test/java/io/denison/typedvalue/MapDelegateTest.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue 2 | 3 | import android.os.Bundle 4 | import io.denison.typedvalue.delegate.MapDelegate 5 | import org.junit.Before 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | import org.robolectric.RobolectricTestRunner 9 | import kotlin.test.assertEquals 10 | import kotlin.test.assertFails 11 | import kotlin.test.assertFalse 12 | import kotlin.test.assertTrue 13 | 14 | @RunWith(RobolectricTestRunner::class) 15 | class MapDelegateTest { 16 | private lateinit var map: MutableMap 17 | private lateinit var delegate: MapDelegate 18 | 19 | @Before 20 | fun setUp() { 21 | map = mutableMapOf( 22 | KEY_INT_DEFAULT to 1, 23 | KEY_BOOLEAN_DEFAULT to true, 24 | KEY_LONG_DEFAULT to 1L, 25 | KEY_STRING_DEFAULT to "default", 26 | KEY_DOUBLE_DEFAULT to 1.0, 27 | KEY_FLOAT_DEFAULT to 1f, 28 | KEY_STRING_LIST_DEFAULT to arrayListOf("default"), 29 | KEY_STRING_SET_DEFAULT to setOf("default"), 30 | KEY_PARCELABLE_DEFAULT to PARCELABLE_BUNDLE 31 | ) 32 | delegate = MapDelegate(map) 33 | } 34 | 35 | @Test 36 | fun testGetInt() { 37 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2)) 38 | assertEquals(2, delegate.getInt(KEY_INT, 2)) 39 | } 40 | 41 | @Test 42 | fun testPutInt() { 43 | delegate.putInt(KEY_INT, 1) 44 | assertEquals(1, map[KEY_INT]) 45 | } 46 | 47 | @Test 48 | fun testGetBoolean() { 49 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) } 50 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) } 51 | } 52 | 53 | @Test 54 | fun testPutBoolean() { 55 | delegate.putBoolean(KEY_BOOLEAN, true) 56 | assertEquals(true, map[KEY_BOOLEAN]) 57 | } 58 | 59 | @Test 60 | fun testGetLong() { 61 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2)) 62 | assertEquals(2, delegate.getLong(KEY_LONG, 2)) 63 | } 64 | 65 | @Test 66 | fun testPutLong() { 67 | delegate.putLong(KEY_LONG, 1) 68 | assertEquals(1L, map[KEY_LONG]) 69 | } 70 | 71 | @Test 72 | fun testGetString() { 73 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val")) 74 | assertEquals("val", delegate.getString(KEY_STRING, "val")) 75 | } 76 | 77 | @Test 78 | fun testPutString() { 79 | delegate.putString(KEY_STRING, "val") 80 | assertEquals("val", map[KEY_STRING]) 81 | } 82 | 83 | @Test 84 | fun testGetDouble() { 85 | assertEquals(1.0, delegate.getDouble(KEY_DOUBLE_DEFAULT, 2.0)) 86 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0)) 87 | } 88 | 89 | @Test 90 | fun testPutDouble() { 91 | delegate.putDouble(KEY_DOUBLE, 2.0) 92 | assertEquals(2.0, map[KEY_DOUBLE]) 93 | } 94 | 95 | @Test 96 | fun testGetFloat() { 97 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f)) 98 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f)) 99 | } 100 | 101 | @Test 102 | fun testPutFloat() { 103 | delegate.putFloat(KEY_FLOAT, 2f) 104 | assertEquals(2f, map[KEY_FLOAT]) 105 | } 106 | 107 | @Test 108 | fun testGetStringSet() { 109 | assertEquals(setOf("default"), delegate.getStringSet(KEY_STRING_SET_DEFAULT, emptySet())) 110 | assertEquals(emptySet(), delegate.getStringSet(KEY_STRING_SET, emptySet())) 111 | } 112 | 113 | @Test 114 | fun testPutStringSet() { 115 | delegate.putStringSet(KEY_STRING_SET, setOf("val")) 116 | assertEquals(setOf("val"), map[KEY_STRING_SET]) 117 | } 118 | 119 | @Test 120 | fun testGetStringList() { 121 | assertEquals(arrayListOf("default"), delegate.getStringList(KEY_STRING_LIST_DEFAULT, emptyList())) 122 | assertEquals(emptyList(), delegate.getStringList(KEY_STRING_LIST, emptyList())) 123 | } 124 | 125 | @Test 126 | fun testPutStringList() { 127 | delegate.putStringList(KEY_STRING_LIST, arrayListOf("val")) 128 | assertEquals(arrayListOf("val"), map[KEY_STRING_LIST]) 129 | } 130 | 131 | @Test 132 | fun testGetParcelable() { 133 | val bundle = Bundle() 134 | assertEquals(PARCELABLE_BUNDLE, delegate.getParcelable(KEY_PARCELABLE_DEFAULT, Bundle())) 135 | assertEquals(bundle, delegate.getParcelable(KEY_PARCELABLE, bundle)) 136 | } 137 | 138 | @Test 139 | fun testPutParcelable() { 140 | delegate.putParcelable(KEY_PARCELABLE, PARCELABLE_BUNDLE) 141 | assertEquals(PARCELABLE_BUNDLE, map[KEY_PARCELABLE]) 142 | } 143 | 144 | @Test 145 | fun testContains() { 146 | assertTrue { KEY_INT_DEFAULT in delegate } 147 | assertTrue { KEY_INT !in delegate } 148 | } 149 | 150 | @Test 151 | fun testRemove() { 152 | delegate.remove(KEY_INT_DEFAULT) 153 | assertTrue { KEY_INT_DEFAULT !in delegate } 154 | assertFalse { map.containsKey(KEY_INT_DEFAULT) } 155 | } 156 | 157 | @Test 158 | fun testClear() { 159 | delegate.clear() 160 | assertTrue { KEY_INT_DEFAULT !in delegate } 161 | assertTrue { map.isEmpty() } 162 | } 163 | 164 | 165 | private companion object { 166 | const val KEY_INT = ".KEY_INT" 167 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT" 168 | const val KEY_BOOLEAN = "KEY_BOOLEAN" 169 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT" 170 | const val KEY_LONG = "KEY_LONG" 171 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT" 172 | const val KEY_STRING = "KEY_STRING" 173 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT" 174 | const val KEY_DOUBLE = "KEY_DOUBLE" 175 | const val KEY_DOUBLE_DEFAULT = "KEY_DOUBLE_DEFAULT" 176 | const val KEY_FLOAT = "KEY_FLOAT" 177 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT" 178 | const val KEY_STRING_SET = "KEY_STRING_SET" 179 | const val KEY_STRING_SET_DEFAULT = "KEY_STRING_SET_DEFAULT" 180 | const val KEY_STRING_LIST = "KEY_STRING_LIST" 181 | const val KEY_STRING_LIST_DEFAULT = "KEY_STRING_LIST_DEFAULT" 182 | const val KEY_PARCELABLE = "KEY_PARCELABLE" 183 | const val KEY_PARCELABLE_DEFAULT = "KEY_PARCELABLE_DEFAULT" 184 | 185 | val PARCELABLE_BUNDLE = Bundle().apply { putInt(KEY_INT, 1) } 186 | } 187 | } -------------------------------------------------------------------------------- /library/src/test/java/io/denison/typedvalue/PreferenceDelegateTest.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue 2 | 3 | import android.content.SharedPreferences 4 | import android.os.Bundle 5 | import android.preference.PreferenceManager 6 | import io.denison.typedvalue.delegate.PreferenceDelegate 7 | import org.junit.Before 8 | import org.junit.Test 9 | import org.junit.runner.RunWith 10 | import org.robolectric.RobolectricTestRunner 11 | import org.robolectric.RuntimeEnvironment 12 | import kotlin.test.assertEquals 13 | import kotlin.test.assertFails 14 | import kotlin.test.assertFalse 15 | import kotlin.test.assertTrue 16 | 17 | @RunWith(RobolectricTestRunner::class) 18 | class PreferenceDelegateTest { 19 | private lateinit var sharedPreferences: SharedPreferences 20 | private lateinit var delegate: PreferenceDelegate 21 | 22 | @Before 23 | fun setUp() { 24 | sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RuntimeEnvironment.application).apply { 25 | edit() 26 | .putInt(KEY_INT_DEFAULT, 1) 27 | .putBoolean(KEY_BOOLEAN_DEFAULT, true) 28 | .putLong(KEY_LONG_DEFAULT, 1) 29 | .putString(KEY_STRING_DEFAULT, "default") 30 | .putFloat(KEY_FLOAT_DEFAULT, 1f) 31 | .putStringSet(KEY_STRING_SET_DEFAULT, setOf("default")) 32 | .commit() 33 | } 34 | delegate = PreferenceDelegate(sharedPreferences) 35 | } 36 | 37 | @Test 38 | fun testGetInt() { 39 | assertEquals(1, delegate.getInt(KEY_INT_DEFAULT, 2)) 40 | assertEquals(2, delegate.getInt(KEY_INT, 2)) 41 | } 42 | 43 | @Test 44 | fun testPutInt() { 45 | delegate.putInt(KEY_INT, 1) 46 | assertEquals(1, sharedPreferences.getInt(KEY_INT, 0)) 47 | } 48 | 49 | @Test 50 | fun testGetBoolean() { 51 | assertTrue { delegate.getBoolean(KEY_BOOLEAN_DEFAULT, false) } 52 | assertFalse { delegate.getBoolean(KEY_BOOLEAN, false) } 53 | } 54 | 55 | @Test 56 | fun testPutBoolean() { 57 | delegate.putBoolean(KEY_BOOLEAN, true) 58 | assertEquals(true, sharedPreferences.getBoolean(KEY_BOOLEAN, false)) 59 | } 60 | 61 | @Test 62 | fun testGetLong() { 63 | assertEquals(1, delegate.getLong(KEY_LONG_DEFAULT, 2)) 64 | assertEquals(2, delegate.getLong(KEY_LONG, 2)) 65 | } 66 | 67 | @Test 68 | fun testPutLong() { 69 | delegate.putLong(KEY_LONG, 1) 70 | assertEquals(1, sharedPreferences.getLong(KEY_LONG, 0)) 71 | } 72 | 73 | @Test 74 | fun testGetString() { 75 | assertEquals("default", delegate.getString(KEY_STRING_DEFAULT, "val")) 76 | assertEquals("val", delegate.getString(KEY_STRING, "val")) 77 | } 78 | 79 | @Test 80 | fun testPutString() { 81 | delegate.putString(KEY_STRING, "val") 82 | assertEquals("val", sharedPreferences.getString(KEY_STRING, "")) 83 | } 84 | 85 | @Test 86 | fun testGetDouble() { 87 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 2.0)) 88 | } 89 | 90 | @Test 91 | fun testPutDouble() { 92 | delegate.putDouble(KEY_DOUBLE, 2.0) 93 | assertEquals(2.0, delegate.getDouble(KEY_DOUBLE, 0.0)) 94 | } 95 | 96 | @Test 97 | fun testGetFloat() { 98 | assertEquals(1f, delegate.getFloat(KEY_FLOAT_DEFAULT, 2f)) 99 | assertEquals(2f, delegate.getFloat(KEY_FLOAT, 2f)) 100 | } 101 | 102 | @Test 103 | fun testPutFloat() { 104 | delegate.putFloat(KEY_FLOAT, 2f) 105 | assertEquals(2f, sharedPreferences.getFloat(KEY_FLOAT, 0f)) 106 | } 107 | 108 | @Test 109 | fun testGetStringSet() { 110 | val set = setOf("val") 111 | assertEquals(setOf("default"), delegate.getStringSet(KEY_STRING_SET_DEFAULT, emptySet())) 112 | assertEquals(set, delegate.getStringSet(KEY_STRING_SET, set)) 113 | } 114 | 115 | @Test 116 | fun testPutStringSet() { 117 | delegate.putStringSet(KEY_STRING_SET, setOf("val")) 118 | assertEquals(setOf("val"), sharedPreferences.getStringSet(KEY_STRING_SET, emptySet())) 119 | } 120 | 121 | @Test 122 | fun testGetStringList() { 123 | assertFails { delegate.getStringList(KEY_STRING_LIST, listOf()) } 124 | } 125 | 126 | @Test 127 | fun testPutStringList() { 128 | assertFails { delegate.putStringList(KEY_STRING_LIST, listOf()) } 129 | } 130 | 131 | @Test 132 | fun testGetParcelable() { 133 | assertFails { delegate.getParcelable(KEY_PARCELABLE, Bundle()) } 134 | } 135 | 136 | @Test 137 | fun testPutParcelable() { 138 | assertFails { delegate.putParcelable(KEY_PARCELABLE, Bundle()) } 139 | } 140 | 141 | @Test 142 | fun testContains() { 143 | assertTrue { KEY_INT_DEFAULT in delegate } 144 | assertTrue { KEY_INT !in delegate } 145 | } 146 | 147 | @Test 148 | fun testRemove() { 149 | delegate.remove(KEY_INT_DEFAULT) 150 | assertTrue { KEY_INT_DEFAULT !in delegate } 151 | assertFalse { sharedPreferences.contains(KEY_INT_DEFAULT) } 152 | } 153 | 154 | @Test 155 | fun testClear() { 156 | delegate.clear() 157 | assertTrue { KEY_INT_DEFAULT !in delegate } 158 | assertTrue { sharedPreferences.all.isEmpty() } 159 | } 160 | 161 | 162 | private companion object { 163 | const val KEY_INT = ".KEY_INT" 164 | const val KEY_INT_DEFAULT = ".KEY_INT_DEFAULT" 165 | const val KEY_BOOLEAN = "KEY_BOOLEAN" 166 | const val KEY_BOOLEAN_DEFAULT = "KEY_BOOLEAN_DEFAULT" 167 | const val KEY_LONG = "KEY_LONG" 168 | const val KEY_LONG_DEFAULT = "KEY_LONG_DEFAULT" 169 | const val KEY_STRING = "KEY_STRING" 170 | const val KEY_STRING_DEFAULT = "KEY_STRING_DEFAULT" 171 | const val KEY_DOUBLE = "KEY_DOUBLE" 172 | const val KEY_FLOAT = "KEY_FLOAT" 173 | const val KEY_FLOAT_DEFAULT = "KEY_FLOAT_DEFAULT" 174 | const val KEY_STRING_SET_DEFAULT = "KEY_STRING_SET_DEFAULT" 175 | const val KEY_STRING_SET = "KEY_STRING_SET" 176 | const val KEY_STRING_LIST = "KEY_STRING_LIST" 177 | const val KEY_PARCELABLE = "KEY_PARCELABLE" 178 | } 179 | } -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android-extensions' 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion versions.compileSdk 8 | buildToolsVersion versions.buildTools 9 | 10 | defaultConfig { 11 | applicationId "io.denison.typedvalue.sample" 12 | 13 | minSdkVersion 19 14 | targetSdkVersion 28 15 | versionCode 1 16 | versionName "1.0" 17 | } 18 | } 19 | 20 | dependencies { 21 | implementation project(':library') 22 | 23 | implementation libraries.kotlinStdLib 24 | implementation libraries.androidAppCompat 25 | implementation libraries.androidAnnotations 26 | implementation libraries.timber 27 | implementation libraries.rxJava2 28 | implementation libraries.rxAndroid2 29 | implementation libraries.rxKotlin 30 | implementation libraries.rxRelay 31 | implementation libraries.constraintLayout 32 | implementation libraries.lottie 33 | 34 | implementation libraries.dagger 35 | kapt libraries.daggerCompiler 36 | } 37 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | class MainActivity: AppCompatActivity() { 7 | override fun onCreate(savedInstanceState: Bundle?) { 8 | super.onCreate(savedInstanceState) 9 | setContentView(R.layout.ac_main) 10 | } 11 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/SampleApplication.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import io.denison.typedvalue.sample.di.AppComponent 6 | import io.denison.typedvalue.sample.di.AppModule 7 | import io.denison.typedvalue.sample.di.DaggerAppComponent 8 | 9 | class SampleApplication : Application() { 10 | private lateinit var component: AppComponent 11 | 12 | override fun onCreate() { 13 | super.onCreate() 14 | 15 | component = DaggerAppComponent.builder() 16 | .appModule(AppModule(this)) 17 | .build() 18 | } 19 | 20 | companion object { 21 | fun appComponent(context: Context): AppComponent = (context.applicationContext as SampleApplication).component 22 | } 23 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/di/AppComponent.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.di 2 | 3 | import dagger.Component 4 | import io.denison.typedvalue.sample.preferences.AppPreferences 5 | import javax.inject.Singleton 6 | 7 | @Singleton 8 | @Component(modules = [AppModule::class]) 9 | interface AppComponent { 10 | fun preferences(): AppPreferences 11 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/di/AppModule.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.di 2 | 3 | import android.app.Application 4 | import dagger.Module 5 | import dagger.Provides 6 | import io.denison.typedvalue.sample.SampleApplication 7 | import io.denison.typedvalue.sample.preferences.AppPreferences 8 | import io.denison.typedvalue.sample.preferences.AppPreferencesImpl 9 | import javax.inject.Singleton 10 | 11 | @Module 12 | class AppModule(private val app: SampleApplication) { 13 | @Singleton 14 | @Provides 15 | fun provideApplication(): Application = app 16 | 17 | @Singleton 18 | @Provides 19 | fun provideAppPreferences(app: Application): AppPreferences = AppPreferencesImpl(app) 20 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/di/ViewScope.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.di 2 | 3 | import javax.inject.Scope 4 | import kotlin.annotation.AnnotationRetention.RUNTIME 5 | 6 | @Scope 7 | @Retention(RUNTIME) 8 | annotation class ViewScope -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/model/AnimationType.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.model 2 | 3 | enum class AnimationType { 4 | CONFETTI, 5 | PLANE, 6 | FAVORITE 7 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/mvp/MvpPresenter.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.mvp 2 | 3 | import androidx.annotation.UiThread 4 | 5 | interface MvpPresenter { 6 | @UiThread fun attachView(view: V) 7 | @UiThread fun detachView() 8 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/mvp/MvpView.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.mvp 2 | 3 | interface MvpView -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/mvp/presenter/BasePresenter.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.mvp.presenter 2 | 3 | import androidx.annotation.CallSuper 4 | import androidx.annotation.UiThread 5 | import io.denison.typedvalue.sample.mvp.MvpPresenter 6 | import io.denison.typedvalue.sample.mvp.MvpView 7 | import io.reactivex.Completable 8 | import io.reactivex.Maybe 9 | import io.reactivex.Observable 10 | import io.reactivex.Single 11 | import io.reactivex.disposables.CompositeDisposable 12 | import io.reactivex.disposables.Disposable 13 | import io.reactivex.exceptions.OnErrorNotImplementedException 14 | import java.lang.ref.WeakReference 15 | 16 | open class BasePresenter : MvpPresenter { 17 | private lateinit var viewRef: WeakReference 18 | 19 | private val viewDisposables: CompositeDisposable = CompositeDisposable() 20 | 21 | protected val view: V? 22 | get() = viewRef.get() 23 | 24 | @CallSuper 25 | @UiThread 26 | override fun attachView(view: V) { 27 | viewRef = WeakReference(view) 28 | } 29 | 30 | @CallSuper 31 | @UiThread 32 | override fun detachView() { 33 | viewDisposables.clear() 34 | viewRef.clear() 35 | } 36 | 37 | protected fun Observable.subscribeUntilDetach( 38 | onNext: (T) -> Unit = {}, 39 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) }, 40 | onComplete: () -> Unit = {} 41 | ): Disposable = subscribe(onNext, onError, onComplete).apply { viewDisposables.add(this) } 42 | 43 | protected fun Maybe.subscribeUntilDetach( 44 | onSuccess: (T) -> Unit = {}, 45 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) }, 46 | onComplete: () -> Unit = {} 47 | ): Disposable = subscribe(onSuccess, onError, onComplete).apply { viewDisposables.add(this) } 48 | 49 | protected fun Single.subscribeUntilDetach( 50 | onSuccess: (T) -> Unit = {}, 51 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) } 52 | ): Disposable = subscribe(onSuccess, onError).apply { viewDisposables.add(this) } 53 | 54 | protected fun Completable.subscribeUntilDetach( 55 | onComplete: () -> Unit = {}, 56 | onError: (Throwable) -> Unit = { throw OnErrorNotImplementedException(it) } 57 | ): Disposable = subscribe(onComplete, onError).apply { viewDisposables.add(this) } 58 | } 59 | -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/mvp/view/MvpConstraintLayout.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.mvp.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.constraintlayout.widget.ConstraintLayout 6 | import io.denison.typedvalue.sample.mvp.MvpPresenter 7 | import io.denison.typedvalue.sample.mvp.MvpView 8 | 9 | abstract class MvpConstraintLayout>(context: Context, attrs: AttributeSet?) 10 | : ConstraintLayout(context, attrs), MvpView { 11 | 12 | protected val presenter: P by lazy { createPresenter() } 13 | 14 | override fun onAttachedToWindow() { 15 | super.onAttachedToWindow() 16 | if (!isInEditMode) { 17 | presenter.attachView(getMvpView()) 18 | } 19 | } 20 | 21 | override fun onDetachedFromWindow() { 22 | if (!isInEditMode) { 23 | presenter.detachView() 24 | } 25 | super.onDetachedFromWindow() 26 | } 27 | 28 | @Suppress("UNCHECKED_CAST") 29 | open fun getMvpView() = this as V 30 | 31 | abstract fun createPresenter(): P 32 | } 33 | -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferences.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.preferences 2 | 3 | import io.denison.typedvalue.common.BoolValue 4 | import io.denison.typedvalue.common.FloatValue 5 | import io.denison.typedvalue.sample.preferences.value.AnimationTypeValue 6 | 7 | interface AppPreferences { 8 | val animationTypeValue: AnimationTypeValue 9 | val scaleValue: FloatValue 10 | val messageShownValue: BoolValue 11 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/preferences/AppPreferencesImpl.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.preferences 2 | 3 | import android.app.Application 4 | import android.preference.PreferenceManager 5 | import io.denison.typedvalue.common.BoolValue 6 | import io.denison.typedvalue.common.FloatValue 7 | import io.denison.typedvalue.delegate.PreferenceDelegate 8 | import io.denison.typedvalue.sample.model.AnimationType 9 | import io.denison.typedvalue.sample.preferences.value.AnimationTypeValue 10 | 11 | class AppPreferencesImpl(app: Application) : AppPreferences { 12 | private val delegate = PreferenceDelegate(PreferenceManager.getDefaultSharedPreferences(app)) 13 | 14 | override val animationTypeValue: AnimationTypeValue by lazy { AnimationTypeValue(delegate, KEY_ANIMATION_TYPE, AnimationType.CONFETTI) } 15 | override val scaleValue: FloatValue by lazy { FloatValue(delegate, KEY_SCALE, 0.8f) } 16 | override val messageShownValue: BoolValue by lazy { BoolValue(delegate, KEY_MESSAGE_SHOWN) } 17 | 18 | private companion object { 19 | const val KEY_ANIMATION_TYPE = ".key_animation_type" 20 | const val KEY_SCALE = ".key_scale" 21 | const val KEY_MESSAGE_SHOWN = ".key_message_shown" 22 | } 23 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/preferences/value/AnimationTypeValue.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.preferences.value 2 | 3 | import io.denison.typedvalue.KeyValueDelegate 4 | import io.denison.typedvalue.TypedValue 5 | import io.denison.typedvalue.sample.model.AnimationType 6 | 7 | class AnimationTypeValue(delegate: KeyValueDelegate, key: String, defaultValue: AnimationType) : TypedValue(delegate, key, defaultValue) { 8 | override fun get(): AnimationType = AnimationType.valueOf(delegate.getString(key, defaultValue.name)) 9 | override fun set(value: AnimationType) = delegate.putString(key, value.name) 10 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationComponent.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.animation 2 | 3 | import dagger.Component 4 | import io.denison.typedvalue.sample.di.AppComponent 5 | import io.denison.typedvalue.sample.di.ViewScope 6 | 7 | @ViewScope 8 | @Component(dependencies = [AppComponent::class]) 9 | interface AnimationComponent { 10 | fun presenter(): AnimationPresenter 11 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationLayout.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.animation 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import io.denison.typedvalue.sample.R 6 | import io.denison.typedvalue.sample.SampleApplication 7 | import io.denison.typedvalue.sample.model.AnimationType 8 | import io.denison.typedvalue.sample.mvp.view.MvpConstraintLayout 9 | import kotlinx.android.synthetic.main.ac_main.view.lottieView 10 | 11 | class AnimationLayout(context: Context, attributeSet: AttributeSet) : MvpConstraintLayout(context, attributeSet), AnimationView { 12 | private lateinit var component: AnimationComponent 13 | 14 | override fun onAttachedToWindow() { 15 | injectDependencies() 16 | super.onAttachedToWindow() 17 | } 18 | 19 | override fun bindTo(type: AnimationType) { 20 | lottieView.setAnimation(when (type) { 21 | AnimationType.FAVORITE -> R.raw.favourite 22 | AnimationType.CONFETTI -> R.raw.confetti 23 | AnimationType.PLANE -> R.raw.plane 24 | }) 25 | lottieView.playAnimation() 26 | } 27 | 28 | override fun bindTo(scale: Float) { 29 | lottieView.scale = scale 30 | } 31 | 32 | 33 | override fun createPresenter(): AnimationPresenter = component.presenter() 34 | 35 | private fun injectDependencies() { 36 | if (isInEditMode) 37 | return 38 | 39 | component = DaggerAnimationComponent.builder() 40 | .appComponent(SampleApplication.appComponent(context)) 41 | .build() 42 | } 43 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationPresenter.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.animation 2 | 3 | import io.denison.typedvalue.sample.mvp.presenter.BasePresenter 4 | import io.denison.typedvalue.sample.preferences.AppPreferences 5 | import io.reactivex.android.schedulers.AndroidSchedulers 6 | import io.reactivex.schedulers.Schedulers 7 | import timber.log.Timber 8 | import javax.inject.Inject 9 | 10 | class AnimationPresenter @Inject constructor( 11 | private val appPreferences: AppPreferences 12 | ) : BasePresenter() { 13 | 14 | override fun attachView(view: AnimationView) { 15 | super.attachView(view) 16 | 17 | appPreferences.animationTypeValue.asObservable().startWith(appPreferences.animationTypeValue.get()) 18 | .subscribeOn(Schedulers.io()) 19 | .observeOn(AndroidSchedulers.mainThread()) 20 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e) 21 | 22 | appPreferences.scaleValue.asObservable().startWith(appPreferences.scaleValue.get()) 23 | .subscribeOn(Schedulers.io()) 24 | .observeOn(AndroidSchedulers.mainThread()) 25 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e) 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/animation/AnimationView.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.animation 2 | 3 | import io.denison.typedvalue.sample.model.AnimationType 4 | import io.denison.typedvalue.sample.mvp.MvpView 5 | 6 | interface AnimationView : MvpView { 7 | fun bindTo(type: AnimationType) 8 | fun bindTo(scale: Float) 9 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsComponent.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.settings 2 | 3 | import dagger.Component 4 | import io.denison.typedvalue.sample.di.AppComponent 5 | import io.denison.typedvalue.sample.di.ViewScope 6 | 7 | @ViewScope 8 | @Component(dependencies = [AppComponent::class]) 9 | interface SettingsComponent { 10 | fun presenter(): SettingsPresenter 11 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsLayout.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.settings 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.SeekBar 6 | import android.widget.SeekBar.OnSeekBarChangeListener 7 | import android.widget.Toast 8 | import com.jakewharton.rxrelay2.PublishRelay 9 | import io.denison.typedvalue.sample.R 10 | import io.denison.typedvalue.sample.SampleApplication 11 | import io.denison.typedvalue.sample.mvp.view.MvpConstraintLayout 12 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewAction 13 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel 14 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel.Content 15 | import io.reactivex.Observable 16 | import kotlinx.android.synthetic.main.ac_main.view.imageTypeSetting 17 | import kotlinx.android.synthetic.main.ac_main.view.imageTypeSettingText 18 | import kotlinx.android.synthetic.main.ac_main.view.scaleSettingValue 19 | 20 | class SettingsLayout(context: Context, attributeSet: AttributeSet) : MvpConstraintLayout(context, attributeSet), SettingsView { 21 | private lateinit var component: SettingsComponent 22 | private lateinit var model: ViewModel.Content 23 | private val actionsRelay = PublishRelay.create() 24 | 25 | override fun onAttachedToWindow() { 26 | injectDependencies() 27 | super.onAttachedToWindow() 28 | } 29 | 30 | override fun onFinishInflate() { 31 | super.onFinishInflate() 32 | imageTypeSetting.setOnClickListener { actionsRelay.accept(ViewAction.AnimationTypeClicked(model.type)) } 33 | scaleSettingValue.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { 34 | override fun onStartTrackingTouch(seekBar: SeekBar?) {} 35 | override fun onStopTrackingTouch(seekBar: SeekBar?) {} 36 | override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { 37 | if (fromUser) 38 | actionsRelay.accept(ViewAction.ScaleChanged(progress)) 39 | } 40 | }) 41 | } 42 | 43 | override fun bindTo(model: ViewModel) = when (model) { 44 | is ViewModel.Content -> bindContent(model) 45 | } 46 | 47 | private fun bindContent(model: Content) { 48 | this.model = model 49 | imageTypeSettingText.text = model.type.name 50 | scaleSettingValue.progress = model.scale 51 | } 52 | 53 | override fun showWelcomeMessage() { 54 | Toast.makeText(context, R.string.animation_playground, Toast.LENGTH_LONG).show() 55 | } 56 | 57 | override fun observeViewActions(): Observable = actionsRelay 58 | 59 | override fun createPresenter(): SettingsPresenter = component.presenter() 60 | 61 | private fun injectDependencies() { 62 | if (isInEditMode) 63 | return 64 | 65 | component = DaggerSettingsComponent.builder() 66 | .appComponent(SampleApplication.appComponent(context)) 67 | .build() 68 | } 69 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsPresenter.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.settings 2 | 3 | import io.denison.typedvalue.sample.model.AnimationType 4 | import io.denison.typedvalue.sample.mvp.presenter.BasePresenter 5 | import io.denison.typedvalue.sample.preferences.AppPreferences 6 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewAction 7 | import io.denison.typedvalue.sample.ui.settings.SettingsView.ViewModel 8 | import io.reactivex.android.schedulers.AndroidSchedulers 9 | import io.reactivex.rxkotlin.Observables 10 | import io.reactivex.schedulers.Schedulers 11 | import timber.log.Timber 12 | import javax.inject.Inject 13 | 14 | class SettingsPresenter @Inject constructor( 15 | private val appPreferences: AppPreferences 16 | ) : BasePresenter() { 17 | 18 | override fun attachView(view: SettingsView) { 19 | super.attachView(view) 20 | 21 | Observables.combineLatest( 22 | appPreferences.animationTypeValue.asObservable().startWith(appPreferences.animationTypeValue.get()), 23 | appPreferences.scaleValue.asObservable().startWith(appPreferences.scaleValue.get()), 24 | { type, scale -> ViewModel.Content(type, (scale * 100).toInt()) } 25 | ) 26 | .subscribeOn(Schedulers.io()) 27 | .observeOn(AndroidSchedulers.mainThread()) 28 | .subscribeUntilDetach(onNext = view::bindTo, onError = Timber::e) 29 | 30 | view.observeViewActions() 31 | .subscribeOn(Schedulers.io()) 32 | .observeOn(Schedulers.io()) 33 | .subscribeUntilDetach(onNext = this::handleViewAction, onError = Timber::e) 34 | 35 | if (!appPreferences.messageShownValue.get()) { 36 | appPreferences.messageShownValue.set(true) 37 | view.showWelcomeMessage() 38 | } 39 | } 40 | 41 | private fun handleViewAction(action: ViewAction) = when (action) { 42 | is ViewAction.ScaleChanged -> appPreferences.scaleValue.set(action.value / 100f) 43 | is ViewAction.AnimationTypeClicked -> appPreferences.animationTypeValue.set(when (action.type) { 44 | AnimationType.CONFETTI -> AnimationType.PLANE 45 | AnimationType.PLANE -> AnimationType.FAVORITE 46 | AnimationType.FAVORITE -> AnimationType.CONFETTI 47 | }) 48 | } 49 | } -------------------------------------------------------------------------------- /sample/src/main/java/io/denison/typedvalue/sample/ui/settings/SettingsView.kt: -------------------------------------------------------------------------------- 1 | package io.denison.typedvalue.sample.ui.settings 2 | 3 | import io.denison.typedvalue.sample.model.AnimationType 4 | import io.denison.typedvalue.sample.mvp.MvpView 5 | import io.reactivex.Observable 6 | 7 | interface SettingsView : MvpView { 8 | fun bindTo(model: ViewModel) 9 | fun showWelcomeMessage() 10 | 11 | fun observeViewActions(): Observable 12 | 13 | sealed class ViewModel { 14 | data class Content(val type: AnimationType, val scale: Int) : ViewModel() 15 | } 16 | 17 | sealed class ViewAction { 18 | data class AnimationTypeClicked(val type: AnimationType) : ViewAction() 19 | data class ScaleChanged(val value: Int) : ViewAction() 20 | } 21 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable-v21/setting_item_bkg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/setting_item_bkg.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 | -------------------------------------------------------------------------------- /sample/src/main/res/font/fonts.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /sample/src/main/res/font/roboto_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/font/roboto_medium.ttf -------------------------------------------------------------------------------- /sample/src/main/res/layout/ac_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 18 | 19 | 27 | 28 | 39 | 40 | 41 | 49 | 50 | 60 | 61 | 74 | 75 | 90 | 91 | 101 | 102 | 115 | 116 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuriDenison/typedvalue/df82eb36b61336badade897534fbeb92fdb2029e/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/raw/confetti.json: -------------------------------------------------------------------------------- 1 | {"v":"4.12.0","fr":29.9700012207031,"ip":0,"op":59.0000024031193,"w":800,"h":800,"nm":"confettis2","ddd":0,"assets":[{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"p20","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[71,152,0],"to":[1.83333337306976,-220.66667175293,0],"ti":[85.1666641235352,-23.3333339691162,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"p19","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[579,746,0],"to":[101.833335876465,91.3333358764648,0],"ti":[27.1666660308838,-153.33332824707,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"p18","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[503,238,0],"to":[-84.1666641235352,-74.6666641235352,0],"ti":[-88.8333358764648,-45.3333320617676,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"p17","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[91,556,0],"to":[-82.1666641235352,-112.666664123535,0],"ti":[73.1666641235352,-199.33332824707,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"p16","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[511,308,0],"to":[77.8333358764648,91.3333358764648,0],"ti":[51.1666679382324,60.6666679382324,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"p15","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[155,280,0],"to":[-30.1666660308838,-122.666664123535,0],"ti":[95.1666641235352,-53.3333320617676,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"p14","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[681,388.872,0],"to":[143.83332824707,49.3333320617676,0],"ti":[-58.8333320617676,48.6666679382324,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"p13","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[257,284,0],"to":[-24.1666660308838,-72.6666641235352,0],"ti":[75.1666641235352,-5.33333349227905,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"p12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[301,474,0],"to":[-14.1666669845581,31.3333339691162,0],"ti":[65.1666641235352,-13.3333330154419,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"p11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[499,570,0],"to":[-8.16666698455811,63.3333320617676,0],"ti":[-62.8333320617676,-29.3333339691162,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"p10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":1,"s":[100],"e":[0]},{"t":40.0000016292334}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":1,"s":[400,400,0],"e":[557,68,0],"to":[81.8333358764648,-104.666664123535,0],"ti":[-58.8333320617676,104.666664123535,0]},{"t":40.0000016292334}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"p9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":2,"s":[100],"e":[0]},{"t":41.0000016699642}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":2,"s":[400,400,0],"e":[715,138,0],"to":[151.83332824707,-46.6666679382324,0],"ti":[-26.8333339691162,72.6666641235352,0]},{"t":41.0000016699642}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"p8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":3,"s":[100],"e":[0]},{"t":42.0000017106951}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":3,"s":[400,400,0],"e":[679,664,0],"to":[107.833335876465,89.3333358764648,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":42.0000017106951}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.074509806931,0.737254917622,0.172549024224,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"p7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":4,"s":[100],"e":[0]},{"t":43.0000017514259}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":4,"s":[400,400,0],"e":[97,686,0],"to":[-36.1666679382324,53.3333320617676,0],"ti":[75.1666641235352,-39.3333320617676,0]},{"t":43.0000017514259}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"p6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":5,"s":[100],"e":[0]},{"t":44.0000017921567}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":5,"s":[400,400,0],"e":[65,340,0],"to":[-148.16667175293,-132.66667175293,0],"ti":[61.1666679382324,-65.3333358764648,0]},{"t":44.0000017921567}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.270588248968,0.529411792755,0.952941179276,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"p5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":6,"s":[100],"e":[0]},{"t":45.0000018328876}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.004,"y":0.691},"o":{"x":0.014,"y":0},"n":"0p004_0p691_0p014_0","t":6,"s":[400,400,0],"e":[400,23.613,0],"to":[-55.3803939819336,-168.204071044922,0],"ti":[27.0301876068115,124.269813537598,0]},{"t":45.0000018328876}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.901960790157,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"p4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":7,"s":[100],"e":[0]},{"t":46.0000018736184}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":7,"s":[400,400,0],"e":[303,660,0],"to":[109.833335876465,69.3333358764648,0],"ti":[97.1666641235352,0.66666668653488,0]},{"t":46.0000018736184}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"p3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":8,"s":[100],"e":[0]},{"t":47.0000019143492}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":8,"s":[400,400,0],"e":[663,498,0],"to":[41.8333320617676,109.333335876465,0],"ti":[-71.8333358764648,39.6666679382324,0]},{"t":47.0000019143492}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.076272718608,0.735462605953,0.171031266451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"p2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":9,"s":[100],"e":[0]},{"t":48.0000019550801}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":9,"s":[400,400,0],"e":[187,88,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[89.1666641235352,6.66666650772095,0]},{"t":48.0000019550801}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.271778345108,0.528400123119,0.952267169952,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"p1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[1],"y":[1]},"o":{"x":[0.01],"y":[0]},"n":["1_1_0p01_0"],"t":0,"s":[100],"e":[0]},{"t":39.0000015885026}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.01,"y":0},"n":"0_1_0p01_0","t":0,"s":[400,400,0],"e":[621,234,0],"to":[-0.16666667163372,-158.66667175293,0],"ti":[-92.8333358764648,-103.333335876465,0]},{"t":39.0000015885026}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[7.855,0],[0,-7.855],[-7.855,0],[0,7.855]],"o":[[-7.855,0],[0,7.855],[7.855,0],[0,-7.855]],"v":[[0,-14.223],[-14.223,0],[0,14.223],[14.223,0]],"c":true},"ix":2},"nm":"Tracé 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.903676450253,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fond 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[80,80],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformer "}],"nm":"Ellipse 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360.000014663101,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":42,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":9.00000036657752,"op":369.000015029678,"st":9.00000036657752,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":267,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":7.00000028511585,"op":367.000014948216,"st":7.00000028511585,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":358,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":5.00000020365417,"op":365.000014866755,"st":5.00000020365417,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":177,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":3.00000012219251,"op":363.000014785293,"st":3.00000012219251,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":132,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":1.00000004073083,"op":361.000014703831,"st":1.00000004073083,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-90,"ix":10},"p":{"a":0,"k":[396,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":8.00000032584668,"op":368.000014988947,"st":8.00000032584668,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":135,"ix":10},"p":{"a":0,"k":[416,420,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":6.00000024438501,"op":366.000014907486,"st":6.00000024438501,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":226,"ix":10},"p":{"a":0,"k":[436,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":4.00000016292334,"op":364.000014826024,"st":4.00000016292334,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":45,"ix":10},"p":{"a":0,"k":[416,380,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[64.5,64.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":2.00000008146167,"op":362.000014744562,"st":2.00000008146167,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"confettis1","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[416,400,0],"ix":2},"a":{"a":0,"k":[400,400,0],"ix":1},"s":{"a":0,"k":[91.5,91.5,100],"ix":6}},"ao":0,"w":800,"h":800,"ip":0,"op":360.000014663101,"st":0,"bm":0}]} -------------------------------------------------------------------------------- /sample/src/main/res/raw/favourite.json: -------------------------------------------------------------------------------- 1 | {"v":"4.5.8","fr":60,"ip":0,"op":80,"w":44,"h":44,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"star Outlines 2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22.385,21.344,0]},"a":{"a":0,"k":[125,125,0]},"s":{"a":1,"k":[{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":14,"s":[0,0,100],"e":[9,9,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":25,"s":[9,9,100],"e":[6,6,100]},{"i":{"x":[0.32,0.32,0.32],"y":[1,1,0.32]},"o":{"x":[0.68,0.68,0.68],"y":[0,0,0.68]},"n":["0p32_1_0p68_0","0p32_1_0p68_0","0p32_0p32_0p68_0p68"],"t":41,"s":[6,6,100],"e":[10,10,100]},{"t":62}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[1.295,0],[1.356,0.96],[-0.521,3.196],[0,0],[0.312,0.315],[0,0],[-1.007,3.01],[-2.957,0.453],[0,0],[-0.175,0.372],[0,0],[-3.091,0],[-1.342,-2.867],[0,0],[0,0],[-0.341,-0.054],[0,0],[-0.972,-2.91],[2.182,-2.246],[0,0],[-0.08,-0.484],[0,0],[2.598,-1.833],[2.651,1.471],[0,0],[0.289,-0.161],[0,0]],"o":[[-1.578,0],[-2.601,-1.826],[0,0],[0.081,-0.484],[0,0],[-2.185,-2.245],[0.974,-2.91],[0,0],[0.345,-0.054],[0,0],[1.346,-2.867],[3.091,0],[0,0],[0,0],[0.175,0.376],[0,0],[2.96,0.453],[1.007,3.007],[0,0],[-0.308,0.322],[0,0],[0.524,3.196],[-2.471,1.738],[0,0],[-0.288,-0.161],[0,0],[-1.191,0.658]],"v":[[-53.993,95.484],[-58.493,94.041],[-61.867,85.891],[-52.366,27.545],[-52.741,26.257],[-92.993,-15.067],[-94.904,-23.585],[-88.533,-29.039],[-32.902,-37.551],[-32.072,-38.229],[-7.193,-91.319],[0.001,-95.968],[7.189,-91.319],[7.197,-91.319],[32.074,-38.235],[32.898,-37.551],[88.527,-29.039],[94.904,-23.585],[92.998,-15.07],[52.742,26.25],[52.366,27.552],[61.865,85.891],[58.502,94.041],[50.212,94.497],[0.454,66.948],[-0.456,66.948],[-50.208,94.497]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[125.015,126.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":14,"op":80,"st":14,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"star Outlines 5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22.385,21.344,0]},"a":{"a":0,"k":[125,125,0]},"s":{"a":0,"k":[10,10,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[1.295,0],[1.356,0.96],[-0.521,3.196],[0,0],[0.312,0.315],[0,0],[-1.007,3.01],[-2.957,0.453],[0,0],[-0.175,0.372],[0,0],[-3.091,0],[-1.342,-2.867],[0,0],[0,0],[-0.341,-0.054],[0,0],[-0.972,-2.91],[2.182,-2.246],[0,0],[-0.08,-0.484],[0,0],[2.598,-1.833],[2.651,1.471],[0,0],[0.289,-0.161],[0,0]],"o":[[-1.578,0],[-2.601,-1.826],[0,0],[0.081,-0.484],[0,0],[-2.185,-2.245],[0.974,-2.91],[0,0],[0.345,-0.054],[0,0],[1.346,-2.867],[3.091,0],[0,0],[0,0],[0.175,0.376],[0,0],[2.96,0.453],[1.007,3.007],[0,0],[-0.308,0.322],[0,0],[0.524,3.196],[-2.471,1.738],[0,0],[-0.288,-0.161],[0,0],[-1.191,0.658]],"v":[[-53.993,95.484],[-58.493,94.041],[-61.867,85.891],[-52.366,27.545],[-52.741,26.257],[-92.993,-15.067],[-94.904,-23.585],[-88.533,-29.039],[-32.902,-37.551],[-32.072,-38.229],[-7.193,-91.319],[0.001,-95.968],[7.189,-91.319],[7.197,-91.319],[32.074,-38.235],[32.898,-37.551],[88.527,-29.039],[94.904,-23.585],[92.998,-15.07],[52.742,26.25],[52.366,27.552],[61.865,85.891],[58.502,94.041],[50.212,94.497],[0.454,66.948],[-0.456,66.948],[-50.208,94.497]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":10},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[125.015,126.016],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":4,"st":-29,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"Dot14","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-320},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"Dot13","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-306.6},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":4,"ty":4,"nm":"Dot12","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-271.7},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":5,"ty":4,"nm":"Dot11","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-258.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.392,0.659,0.086,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":6,"ty":4,"nm":"Dot10","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-220.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.941,0.561,0,1],"e":[0.173,0.569,0.788,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":7,"ty":4,"nm":"Dot9","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-206.9},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-29,"s":[0.941,0.561,0,1],"e":[0.392,0.659,0.086,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.392,0.659,0.086,1],"e":[0.173,0.569,0.788,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":0,"k":44,"ix":1},"e":{"a":0,"k":45,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":8,"ty":4,"nm":"Dot8","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-168.2},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.941,0.561,0,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":9,"ty":4,"nm":"Dot7","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-154.8},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.329,0.596,0.8,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.329,0.596,0.8,1],"e":[0.549,0.275,0.71,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":10,"ty":4,"nm":"Dot6","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-117.1},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.702,0.843,0.659,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tm","s":{"a":0,"k":29,"ix":1},"e":{"a":0,"k":30,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":4,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":11,"ty":4,"nm":"Dot5","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-103.7},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.722,0.847,0.949,1],"e":[0.173,0.569,0.788,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.173,0.569,0.788,1],"e":[0.392,0.659,0.086,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":12,"ty":4,"nm":"Dot4","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-69.3},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.702,0.847,0.659,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":13,"ty":4,"nm":"Dot3","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-55.9},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.643,0.812,0.973,1],"e":[0.173,0.569,0.788,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[0.173,0.569,0.788,1],"e":[0.549,0.275,0.71,1]},{"t":37}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":14,"ty":4,"nm":"Dot2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":-13.4},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[47],"e":[29]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[29],"e":[9]},{"t":49}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[48],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[10]},{"t":49}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.631,0.51,0.624,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[5],"e":[2]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[2],"e":[0]},{"t":41}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":15,"ty":4,"nm":"Dot1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-37.5,-40.5],[-1,0.5]],"c":false}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[44],"e":[19]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[19],"e":[0]},{"t":60}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[45],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[20],"e":[1]},{"t":60}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim"},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0.173,0.569,0.788,1],"e":[0.941,0.561,0,1]},{"t":27}]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[5],"e":[0]},{"t":60}]},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"mn":"ADBE Vector Group"}],"ip":15,"op":61,"st":-73,"bm":0,"sr":1},{"ddd":0,"ind":16,"ty":4,"nm":"C2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[40,40,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":9,"s":[25.744,25.744],"e":[60.744,60.744]},{"t":16}]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"st","c":{"a":0,"k":[0.941,0.561,0,1]},"o":{"a":0,"k":100},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9,"s":[23.3],"e":[1]},{"t":16}]},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":2,"mn":"ADBE Vector Group"}],"ip":9,"op":17,"st":-76,"bm":0,"sr":1},{"ddd":0,"ind":17,"ty":4,"nm":"C1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[22,22,0]},"a":{"a":0,"k":[0,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":4,"s":[4,4,100],"e":[40,40,100]},{"t":10}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[57.344,57.344]},"p":{"a":0,"k":[0,0]},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse"},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":4,"s":[0.941,0.561,0,1],"e":[0.812,0.565,0.969,1]},{"t":10}]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"mn":"ADBE Vector Group"}],"ip":4,"op":10,"st":-75,"bm":0,"sr":1}]} -------------------------------------------------------------------------------- /sample/src/main/res/raw/plane.json: -------------------------------------------------------------------------------- 1 | {"v":"4.5.9","fr":29.9700012207031,"ip":0,"op":87.0000035435826,"w":350,"h":350,"ddd":0,"assets":[],"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Earth Outline","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":0,"k":[175,175,0]},"a":{"a":0,"k":[30,30,0]},"s":{"a":0,"k":[235,235,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[11.238,-3.576],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.491,2.648],[-0.322,0.244],[-0.809,1.455],[0.254,0.981],[-0.086,1.297],[0.058,0.483],[-0.104,1.657],[0.728,0.741],[-5.105,2.693],[-0.016,-0.329],[0,0],[0,0],[-0.578,0.534],[-0.53,0.196],[0.038,-0.214],[1.318,-0.692],[-0.184,-2.341],[0,0],[0,0],[-0.923,0],[-1.77,1.353],[-1.962,0],[-1.56,0.67],[-0.514,0.064],[0.172,-0.579],[0.69,0],[0.224,0.228],[1.738,-1.812],[-0.082,-1.981],[0,0],[0.12,0.054],[0.902,0],[0.163,-0.244],[-0.296,-0.703],[0.728,-1.222],[-0.433,-0.761],[-0.73,0],[-1.555,0.37],[-0.268,0],[-0.336,-0.928],[-0.862,-0.664],[-0.46,0],[-0.188,0.611],[-0.018,0.06],[-0.021,-0.232],[-0.47,0],[-1.023,0.474],[-0.257,0.005],[-0.042,-0.254],[-0.51,-0.775],[-3.249,0],[-1.154,1.791],[-0.17,1.174],[-0.397,0.274],[-1.196,-1.563],[-0.853,0],[0,0],[-0.269,0.306]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.183,-2.332],[0.317,-0.291],[0.807,-0.609],[0.734,-1.321],[-0.156,-0.594],[0.113,-1.697],[-0.049,-0.419],[0.119,-1.901],[2.634,-5.139],[-0.179,0.521],[0,0],[0,0],[0.409,0],[2.67,-2.462],[-0.004,0.12],[-0.193,1.072],[-1.65,0.869],[0,0],[0,0],[0.985,0.385],[2.54,0],[1.597,-1.22],[1.045,0],[0.909,-0.391],[1.124,0.896],[-0.513,1.709],[-0.1,0],[-1.647,-1.646],[-1.305,1.36],[0,0],[-0.123,-0.055],[-1.414,-0.644],[-0.784,0],[-0.475,0.717],[0.695,1.661],[-0.524,0.878],[0.269,0.473],[0.632,0],[0.396,-0.096],[0.546,0],[0.254,0.701],[0.535,0.41],[1.19,0],[0.015,-0.053],[0.083,0.09],[0.106,1.292],[0.458,0],[0.901,-0.411],[0.065,0.163],[0.115,0.676],[1.587,2.4],[1.945,0],[0.277,-0.431],[0.118,-0.819],[0.005,0],[0.48,0.629],[0,0],[0.472,0],[-0.103,12.386]],"v":[[8.474,26.686],[8.91,24.086],[12.306,21.33],[14.25,15.266],[6.25,15.233],[4.691,12.411],[-1.113,8.062],[-4.88,8.209],[-8.29,7.136],[-10.107,5.883],[-9.594,5.712],[-10.536,5.587],[-11.44,4.964],[-12.821,5.284],[-15.189,4.969],[-18.473,6.561],[-18.79,6.666],[-18.772,6.731],[-21.627,8.089],[-24.985,12.614],[-27.523,5.116],[-26.574,4.333],[-24.124,1.639],[-23.757,-1.405],[-24.001,-3.966],[-24.004,-6.647],[-24,-9.157],[-24.931,-12.72],[-13.021,-24.776],[-13.279,-23.558],[-13.234,-22.604],[-12.28,-22.604],[-11.136,-23.282],[-6.733,-26.666],[-6.792,-26.172],[-9.549,-23.751],[-13.067,-19.463],[-13.018,-18.839],[-12.435,-18.61],[-9.559,-18.028],[-3.418,-20.782],[1.648,-23.154],[5.726,-24.458],[8.374,-25.439],[8.867,-22.059],[6.511,-19.073],[6.027,-19.327],[0.197,-19.007],[-1.757,-13.668],[-1.724,-13.2],[-2.087,-13.365],[-5.626,-14.564],[-6.96,-13.911],[-6.856,-11.59],[-7.794,-7.187],[-8.338,-4.787],[-6.833,-4.075],[-3.672,-4.61],[-2.674,-4.753],[-1.711,-3.74],[-0.28,-1.504],[1.18,-0.9],[2.907,-2.652],[2.96,-2.827],[3.074,-2.386],[4.455,-0.899],[6.517,-1.559],[8.12,-2.06],[8.289,-1.279],[9.054,1.013],[17.078,5.995],[21.816,3.257],[22.365,1.019],[23.192,-2.251],[24.901,-0.644],[26.897,0.708],[26.898,0.708],[27.995,0.233]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ind":1,"ty":"sh","ks":{"a":0,"k":{"i":[[0,13.734],[0.671,2.488],[0,0],[0,0],[0.012,0.044],[0.271,0.731],[0.006,0.021],[0.301,0.657],[0.054,0.114],[0.337,0.6],[0.088,0.152],[0.382,0.563],[0.069,0.1],[0.398,0.499],[0.075,0.09],[0.489,0.518],[0.076,0.079],[6.459,1.095],[0.042,0.006],[0.76,0.067],[0.124,0.008],[0.768,0],[0.513,-0.026],[0.007,-0.001],[3.244,-1.383],[0,0],[0,0],[0,-12.178],[-3.848,-5.044],[0,0],[0,0],[-0.147,-0.181],[-0.08,-0.095],[-0.105,-0.121],[0,0],[0,0],[-4.412,-1.778],[0,0],[0,0],[-0.059,-0.022],[-0.183,-0.065],[-0.259,-0.083],[-0.208,-0.06],[-0.246,-0.065],[-0.213,-0.052],[-0.253,-0.056],[-0.211,-0.041],[-0.268,-0.045],[-0.203,-0.028],[-0.287,-0.033],[-0.192,-0.019],[-0.323,-0.02],[-0.16,-0.007],[-0.487,0],[-0.577,0.032],[-0.182,0.013],[-0.395,0.045],[-0.21,0.03],[-0.364,0.063],[-0.215,0.042],[-0.39,0.093],[-0.148,0.038],[0,0],[0,0]],"o":[[0,-2.698],[0,0],[0,0],[-0.013,-0.046],[-0.214,-0.756],[-0.008,-0.021],[-0.255,-0.682],[-0.053,-0.115],[-0.295,-0.625],[-0.086,-0.152],[-0.346,-0.59],[-0.07,-0.101],[-0.366,-0.524],[-0.073,-0.09],[-0.45,-0.552],[-0.075,-0.081],[-4.359,-4.53],[-0.042,-0.008],[-0.744,-0.123],[-0.123,-0.011],[-0.753,-0.057],[-0.516,0],[-0.006,0],[-3.521,0.181],[0,0],[0,0],[-10.449,4.697],[0,6.821],[0,0],[0,0],[0.141,0.183],[0.077,0.097],[0.103,0.124],[0,0],[0,0],[3.086,3.523],[0,0],[0,0],[0.059,0.022],[0.183,0.068],[0.257,0.09],[0.205,0.065],[0.246,0.073],[0.212,0.058],[0.252,0.063],[0.209,0.045],[0.265,0.052],[0.202,0.034],[0.284,0.042],[0.19,0.023],[0.32,0.03],[0.16,0.011],[0.486,0.024],[0.585,0],[0.18,-0.012],[0.399,-0.031],[0.211,-0.025],[0.366,-0.05],[0.215,-0.038],[0.395,-0.079],[0.149,-0.037],[0,0],[0,0],[12.613,-3.546]],"v":[[30,0],[28.965,-7.8],[28.966,-7.808],[28.906,-8.027],[28.864,-8.159],[28.142,-10.392],[28.119,-10.454],[27.279,-12.461],[27.123,-12.805],[26.17,-14.642],[25.908,-15.098],[24.821,-16.831],[24.609,-17.128],[23.463,-18.663],[23.246,-18.938],[21.835,-20.54],[21.608,-20.779],[5.031,-29.569],[4.906,-29.591],[2.651,-29.876],[2.281,-29.903],[0,-30],[-1.541,-29.96],[-1.563,-29.959],[-11.746,-27.61],[-12.25,-27.396],[-12.253,-27.373],[-30,0],[-23.86,18.157],[-23.854,18.184],[-23.717,18.36],[-23.276,18.899],[-23.041,19.187],[-22.734,19.561],[-22.596,19.723],[-22.564,19.738],[-11.172,27.834],[-11.17,27.851],[-10.62,28.06],[-10.442,28.123],[-9.893,28.317],[-9.12,28.579],[-8.5,28.766],[-7.761,28.976],[-7.124,29.138],[-6.366,29.315],[-5.737,29.444],[-4.937,29.587],[-4.331,29.683],[-3.474,29.792],[-2.903,29.858],[-1.938,29.931],[-1.46,29.963],[0,30],[1.741,29.947],[2.282,29.905],[3.474,29.793],[4.107,29.712],[5.202,29.54],[5.848,29.424],[7.022,29.163],[7.472,29.062],[8.103,28.901],[8.108,28.878]],"c":true}},"nm":"Path 2","mn":"ADBE Vector Shape - Group"},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge"},{"ty":"mm","mm":4,"nm":"Merge Paths 2","mn":"ADBE Vector Filter - Merge"},{"ty":"fl","c":{"a":0,"k":[0.137,0.118,0.122,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[30,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":5,"mn":"ADBE Vector Group"}],"ip":0,"op":900.000036657751,"st":0,"bm":0,"sr":1},{"ddd":0,"ind":1,"ty":4,"nm":"Plane Outline","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":0,"s":[0],"e":[359]},{"t":87.0000035435826}]},"p":{"a":0,"k":[175,175,0]},"a":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":16,"s":[174.42,246.5,0],"e":[174.42,232.5,0],"to":[0,-2.33333325386047,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":43,"s":[174.42,232.5,0],"e":[174.42,246.5,0],"to":[0,0,0],"ti":[0,-2.33333325386047,0]},{"t":69.0000028104276}]},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[150,150,100],"e":[186,186,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":43,"s":[186,186,100],"e":[150,150,100]},{"t":69.0000028104276}]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-10.521,3.811],[-0.007,5.58],[5.236,1.909],[11.201,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.132,0],[0,0],[0.676,-0.952],[0,-0.745],[-0.134,-0.383],[0,0],[0,0],[0,0],[1.458,0],[0,0],[0.673,-1.006],[-0.466,-1.118],[0,0],[0,0],[0,0],[0,0],[0,-0.469],[-0.401,-0.604],[-1.208,0],[0,0],[-0.561,1.346],[0,0],[0,0],[0,0],[0,-0.395],[-0.445,-0.618],[-1.168,0],[0,0],[-0.687,0.905]],"o":[[0,0],[0,0],[0,0],[11.125,0],[5.248,-1.903],[0,-5.588],[-10.514,-3.838],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.687,-0.901],[0,0],[-1.168,0],[-0.445,0.622],[0,0.394],[0,0],[0,0],[0,0],[-0.561,-1.346],[0,0],[-1.208,0],[-0.676,1.009],[0,0],[0,0],[0,0],[0,0],[-0.188,0.448],[0,0.703],[0.673,1.005],[0,0],[1.458,0],[0,0],[0,0],[0,0],[-0.134,0.383],[0,0.741],[0.676,0.956],[0,0],[1.132,0],[0,0]],"v":[[-6.09,90.416],[21.346,54.25],[48.785,18.076],[67.356,18.083],[99.946,12.348],[108.593,0.033],[99.975,-12.3],[67.252,-18.083],[48.778,-18.09],[21.346,-54.25],[10.944,-68.716],[-6.09,-90.417],[-18.724,-107.071],[-21.606,-108.5],[-43.306,-108.5],[-46.25,-106.984],[-46.923,-104.883],[-46.724,-103.704],[-17.212,-18.112],[-68.641,-15.053],[-90.751,-44.792],[-94.09,-47.017],[-104.788,-47.017],[-107.799,-45.407],[-108.128,-42.007],[-94.462,-5.212],[-97.408,0.5],[-94.408,6.5],[-108.128,42.008],[-108.406,43.399],[-107.799,45.407],[-104.788,47.017],[-94.09,47.017],[-90.751,44.792],[-68.641,15.396],[-17.19,18.055],[-46.724,103.704],[-46.923,104.883],[-46.25,106.98],[-43.306,108.5],[-21.606,108.5],[-18.724,107.067]],"c":true}},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0.014,0,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[174.407,174.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[13.48,13.48],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"mn":"ADBE Vector Group"}],"ip":0,"op":900.000036657751,"st":0,"bm":0,"sr":1}]} -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #4D000000 5 | #03A9F4 6 | #797A7C 7 | 8 | -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | TypedValue 3 | Image type 4 | Welcome to TypedValue demo! 5 | Image scale 6 | 7 | -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 18 | 19 | 24 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':library' 2 | include ':library-date' 3 | include ':sample' 4 | --------------------------------------------------------------------------------